Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

第八题:对一个很长的名字数组,做分片更新名字请求 #13

Closed
KieSun opened this issue Mar 17, 2021 · 44 comments
Closed

Comments

@KieSun
Copy link
Owner

KieSun commented Mar 17, 2021

/*
 * 对一个很长的名字数组,做分片更新名字请求:
 * 1. 分片里的更新是并行的,执行 changeName
 * 2. 各个分片间是串行的,执行 sleep
 * 这个函数接受三个参数,名字列表、分片数量,每次分片后的等待时间
 * 比如:
 * slicePostTask(['aa', 'bb', 'cc', 'dd', 'ee', 'ff', 'gg', 'hh'], 2, 2000)
 * // => ['aa', 'bb']
 * waiting 2s
 * // => ['cc', 'dd']
 * waiting 2s
 * // => ['ee', 'ff']
 * waiting 2s
 * // => ['gg', 'hh']
 */

const changeName = (name) => new Promise((resolve, reject) => {
  setTimeout(() => resolve(name), 1000)
})

const sleep = time => new Promise((resolve, reject) => {
  setTimeout(resolve, time)
})

const slicePostTask = async (names, chunkSize, time) => {
  // todo
}

去答题

新建了一个大厂真题每日打卡群,有意愿学习打卡的再进,群已达扫码上线,请加好友拉你进群

@KieSun KieSun added the 阿里 label Mar 17, 2021
@turkyden
Copy link

turkyden commented Mar 17, 2021

Typescript 版本实现 👋

破题秘诀:

  1. 先将任务分片成 chunk
  2. 使用 Promise.all 执行并发任务
  3. 使用经典 for 循环结合 async/await 语法糖实现串行顺序执行任务队列。
type ChangeName = <T>(name: T) => Promise<T>;
type Sleep = (time: number) => Promise<void>;
type SlicePostTask = <T>(
  names: Array<T>,
  chunkSize: number,
  time: number
) => void;

const changeName: ChangeName = (name) =>
  new Promise((resolve, reject) => {
    setTimeout(() => resolve(name), 1000);
  });

const sleep: Sleep = (time) =>
  new Promise((resolve, reject) => {
    setTimeout(resolve, time);
  });

const slicePostTask: SlicePostTask = async (names, chunkSize, time) => {
  // => [['aa', 'bb'], ['cc', 'dd'], ['ee', 'ff'], ['gg', 'hh']]
  const chunks = Array.from(
    Array(Math.ceil(names.length / chunkSize)),
    (v, k) => names.slice(k * chunkSize, k * chunkSize + chunkSize)
  );
  for (let index = 0; index < chunks.length; index++) {
    const chunk = chunks[index];
    const promiseArray = chunk.map(changeName);
    const name = await Promise.all(promiseArray);
    console.log(name);
    await sleep(time);
  }
};

测试:

slicePostTask(["aa", "bb", "cc", "dd", "ee", "ff", "gg", "hh"], 2, 2000);

输出:

["aa", "bb"]
// waiting 2s 
["cc", "dd"]
// waiting 2s 
["ee", "ff"]
// waiting 2s 
["gg", "hh"] 

Edit 8-分片请求

@QuXiaoMing
Copy link

QuXiaoMing commented Mar 17, 2021

const changeName = (name) => new Promise((resolve, reject) => {
    setTimeout(() => {
        console.log("changeName -> name", name)
        resolve(name)
    }, 1000)
})

const sleep = time => new Promise((resolve, reject) => {
    console.log("sleep", time)
    setTimeout(resolve, time)
})

const slicePostTask = async (names, chunkSize, time) => {
    if (!names || !names.length) {
        console.log('finished')
        return 0
    }
     const task = names.splice(0, chunkSize)
     await Promise.all(task.map(changeName))
     await sleep(time)
     return slicePostTask(names, chunkSize, time)
}

slicePostTask(['aa', 'bb', 'cc', 'dd', 'ee', 'ff', 'gg', 'hh'], 2, 2000)

changeName -> name aa
changeName -> name bb
sleep 2000
changeName -> name cc
changeName -> name dd
sleep 2000
changeName -> name ee
changeName -> name ff
sleep 2000
changeName -> name gg
changeName -> name hh
sleep 2000
finished

@ByeLe
Copy link

ByeLe commented Mar 17, 2021

const changeName = (name) => new Promise((resolve, reject) => {
    setTimeout(() => resolve(name), 1000)
  })
  
  const sleep = time => new Promise((resolve, reject) => {
    setTimeout(resolve, time)
  })
  
  const slicePostTask = async (names, chunkSize, time) => {
      if (!names.length) {
          return;
      }
      const reqArr = names.length < chunkSize ? names : names.slice(0,chunkSize);
      await changeName(reqArr).then((res) => {
          console.log(res);
          if (reqArr.length === names.length) { // 最后一次请求
            return;
          }
          console.log(`wating${time / 1000}s`);
      });
      await sleep(time)
      slicePostTask(names.slice(chunkSize, names.length), chunkSize, time);
  }
  slicePostTask(['aa', 'bb', 'cc', 'dd', 'ee', 'ff', 'gg', 'hh'], 2, 2000);
// [ 'aa', 'bb' ]
// wating2s
// [ 'cc', 'dd' ]
// wating2s
// [ 'ee', 'ff' ]
// wating2s
// [ 'gg', 'hh' ]

@liuy1994
Copy link

/*
 * 对一个很长的名字数组,做分片更新名字请求:
 * 1. 分片里的更新是并行的,执行 changeName
 * 2. 各个分片间是串行的,执行 sleep
 * 这个函数接受三个参数,名字列表、分片数量,每次分片后的等待时间
 * 比如:
 * slicePostTask(['aa', 'bb', 'cc', 'dd', 'ee', 'ff', 'gg', 'hh'], 2, 2000)
 * // => ['aa', 'bb']
 * waiting 2s
 * // => ['cc', 'dd']
 * waiting 2s
 * // => ['ee', 'ff']
 * waiting 2s
 * // => ['gg', 'hh']
 */

const changeName = (name) => new Promise((resolve, reject) => {
    setTimeout(() => resolve(name), 1000)
})

const sleep = time => new Promise((resolve, reject) => {
    setTimeout(resolve, time)
})

const slicePostTask = async (names, chunkSize, time) => {
    while (names.length) {
        const current = names.splice(0, chunkSize)
        console.log('// => ' + JSON.stringify(current))
        await changeName(current)
        if (names.length) {
            console.log(`waiting ${time / 1000}s`)
            await sleep(time)
        }
    }
}
slicePostTask(['aa', 'bb', 'cc', 'dd', 'ee', 'ff', 'gg', 'hh'], 2, 2000)

@XianHuiDeDiZhongHai
Copy link

const changeName = (name) => new Promise((resolve, reject) => {
  setTimeout(resolve, 1000, name)
})

const sleep = time => new Promise((resolve, reject) => {
  console.log(`waiting ${time/1000}s`)
  setTimeout(resolve, time)
})

const slicePostTask = async (names, chunkSize, time) => {
  const resultArr = await Promise.all(names.slice(0, chunkSize).map(item => changeName(item)))
  console.log(resultArr)
  if (names.length > chunkSize) {
    await sleep(time)
    slicePostTask(names.slice(chunkSize), chunkSize, time)
  }
}

slicePostTask(['aa', 'bb', 'cc', 'dd', 'ee', 'ff', 'gg', 'hh'], 2, 2000)
/**
 * => ['aa', 'bb']
 * 
 * waiting 2s
 * 
 * => ['cc', 'dd']
 * 
 * waiting 2s
 * 
 * => ['ee', 'ff']
 * 
 * waiting 2s
 * 
 * => ['gg', 'hh']
 */

@XINXINP
Copy link

XINXINP commented Mar 17, 2021

const changeName = (name) => new Promise((resolve, reject) => {
    console.log(name);
    setTimeout(() => resolve(name), 1000)
  })
  
  const sleep = time => new Promise((resolve, reject) => {
console.log(`wating ${time}s`)
    setTimeout(resolve, time)
  })
  
  const slicePostTask = async (names, chunkSize, time) => {
      //todo
      names.splice(0,chunkSize).map((name)=>changeName(name))
      if(names == 0)return
      sleep(time).then(()=>{
        slicePostTask(names,chunkSize,time)
      })
  }
  slicePostTask(['aa', 'bb', 'cc', 'dd', 'ee', 'ff', 'gg', 'hh'], 2, 2000)

@l0ng09
Copy link

l0ng09 commented Mar 17, 2021

/*
 * 对一个很长的名字数组,做分片更新名字请求:
 * 1. 分片里的更新是并行的,执行 changeName
 * 2. 各个分片间是串行的,执行 sleep
 * 这个函数接受三个参数,名字列表、分片数量,每次分片后的等待时间
 * 比如:
 * slicePostTask(['aa', 'bb', 'cc', 'dd', 'ee', 'ff', 'gg', 'hh'], 2, 2000)
 * // => ['aa', 'bb']
 * waiting 2s
 * // => ['cc', 'dd']
 * waiting 2s
 * // => ['ee', 'ff']
 * waiting 2s
 * // => ['gg', 'hh']
 */

const changeName = (name) => new Promise((resolve, reject) => {
  setTimeout(() => resolve(name), 1000)
})

const sleep = time => new Promise((resolve, reject) => {
  setTimeout(resolve, time)
})

const slicePostTask = async (names, chunkSize, time) => {
  // todo
  // 对数组进行分片
  let result  = []
  for(let i = 0; i < names.length ; i+= chunkSize){
    result.push(names.slice(i,i+chunkSize))
  }

  // 循环处理分片的数组
  while( result.length > 0){
    const promiseArr = result.shift().map(item=>changeName(item))
    await Promise.all(promiseArr).then(res=>console.log(res), error=>console.log(error))
    await sleep(2000)
  }
}

slicePostTask(['aa', 'bb', 'cc', 'dd', 'ee', 'ff', 'gg', 'hh'], 2, 2000)

@yxlazy
Copy link

yxlazy commented Mar 17, 2021

/*
 * 对一个很长的名字数组,做分片更新名字请求:
 * 1. 分片里的更新是并行的,执行 changeName
 * 2. 各个分片间是串行的,执行 sleep
 * 这个函数接受三个参数,名字列表、分片数量,每次分片后的等待时间
 * 比如:
 * slicePostTask(['aa', 'bb', 'cc', 'dd', 'ee', 'ff', 'gg', 'hh'], 2, 2000)
 * // => ['aa', 'bb']
 * waiting 2s
 * // => ['cc', 'dd']
 * waiting 2s
 * // => ['ee', 'ff']
 * waiting 2s
 * // => ['gg', 'hh']
 */

const changeName = (name) => new Promise((resolve, reject) => {
  setTimeout(() => {
    console.log('=>', name)
    resolve(name)
  }, 1000)
})

const sleep = time => new Promise((resolve, reject) => {
  setTimeout(() => {
    console.log('waiting', time)
    resolve()
  }, time)
})

const slicePostTask = async (names, chunkSize, time) => {
  // todo
  if (!names || !names.length) return []

  let start = 0
  let length = names.length

  while (start < length) {
    await changeName(names.slice(start, start += chunkSize))
    await sleep(time)
  }
}

slicePostTask(['aa', 'bb', 'cc', 'dd', 'ee', 'ff', 'gg', 'hh'], 2, 2000)

@TMBeliever
Copy link

TMBeliever commented Mar 17, 2021

const changeName = (name) => new Promise((resolve, reject) => {
  setTimeout(() => resolve(name), 1000)
})

const sleep = time => new Promise((resolve, reject) => {
  setTimeout(resolve, time)
})

const slicePostTask = async (names, chunkSize, time) => {
  if (!chunkSize || !names.length) return
  while (names.length) {
    await Promise.all(names.splice(0, chunkSize).map(changeName))
    names.length && await sleep(time)
  }
}

@1742284240
Copy link

1742284240 commented Mar 17, 2021

const changeName = (name) =>
  new Promise((resolve, reject) => {
    setTimeout(() => resolve(name), 2000);
  });

const sleep = (time) =>
  new Promise((resolve, reject) => {
    setTimeout(resolve, time);
  });

const slicePostTask = async (names, chunkSize, time) => {
  for (let i = 0; i < Math.ceil(names.length / chunkSize); i++) {
    // console.time(`第${i}次循环耗时`);
    changeName(names.slice(i * chunkSize, (i + 1) * chunkSize)).then((res) => {
      console.log(res, new Date().getMinutes() + ":" + new Date().getSeconds());
    });
    await sleep(time);
    // console.timeEnd(`第${i}次循环耗时`);
  }
};
console.log(
  "开始时间",
  new Date().getMinutes() + ":" + new Date().getSeconds()
);
slicePostTask(["aa", "bb", "cc", "dd", "ee", "ff", "gg", "hh"], 2, 2000);

Edit https://github.com/KieSun/fucking-frontend/issues/13

image

@Xchen1995
Copy link

Xchen1995 commented Mar 17, 2021

const changeName = (name) => new Promise((resolve, reject) => {
  setTimeout(() => resolve(name), 1000)
})

const sleep = time => new Promise((resolve, reject) => {
  setTimeout(resolve, time)
})

const slicePostTask = async (names, chunkSize, time) => {
  let index = 0
  while (index < names.length) {
    let arr = []
    for (let i = 0; i < chunkSize; i++) {
      if (names[index + i]) {
        arr.push(changeName(names[index + i]))        
      }
    }
    index += chunkSize
    await Promise.all(arr).then(res => {
      console.log(res)
    })
    if (index < names.length) {
      await sleep(time)
    }
  }
}

@yancongwen
Copy link

const changeName = name => new Promise((resolve, reject) => {
    setTimeout(() => resolve(name), 1000)
})

const sleep = time => new Promise((resolve, reject) => {
    setTimeout(resolve, time)
})

const slicePostTask = async (names, chunkSize, time) => {
    let i = 0
    let n = names.length
    while (i < n) {
        let chunk = names.slice(i, i + chunkSize)
        let promises = chunk.map(item => {
            return changeName(item)
        })
        await Promise.all(promises).then(res => {
            console.log(res)
        })
        await sleep(time)
        i += chunkSize
    }
}

slicePostTask(['aa', 'bb', 'cc', 'dd', 'ee', 'ff', 'gg', 'hh'], 2, 2000)

@abu-ab
Copy link

abu-ab commented Mar 17, 2021

const changeName = (name) =>
  new Promise((resolve, reject) => {
    setTimeout(() => resolve(name), 1000);
  });

const sleep = (time) =>
  new Promise((resolve, reject) => {
    console.log(`waiting ${time / 1000}s`);
    setTimeout(resolve, time);
  });

const slicePostTask = async (names, chunkSize, time) => {
  // todo
  let arr = [];
  while (arr.length < chunkSize && names.length > 0) {
    await changeName(names.shift()).then((res) => {
      arr.push(res);
    });
  }
  console.log(arr);
  if (names.length == 0) {
    return;
  } else {
    await sleep(time).then((res) => {
      console.log(`waiting ${time / 1000}s`);
      slicePostTask(names, chunkSize, time);
    });
  }
};
slicePostTask(["aa", "bb", "cc", "dd", "ee", "ff", "gg", "hh"], 2, 2000);

image

@xiaofan-love
Copy link

✏️ 自我解析:

const changeName = (name) =>
  new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve(name)
        console.log('request: ' + name)
    }, 1000);
  });

const sleep = (time) =>
  new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve()
        console.log('wait: ' + time + 's')
    }, time);
  });

const slicePostTask = async (names, chunkSize, time) => {
  if (!names.length) {
      console.log('---task over---')
      return
  };
  // 获取分割切片数组,并删除原数组
  let taskNames = names.splice(0, chunkSize);
  console.log("切片:" + taskNames)
  // 并行处理切片
  await Promise.all(taskNames.map(changeName));
  // 串行执行sleep
  await sleep(time);
  // 继续执行切片分割请求
  return slicePostTask(names, chunkSize, time);
};

🏷️ 测试用例

slicePostTask(["aa", "bb", "cc", "dd", "ee", "ff", "gg", "hh"], 2, 2000);

✅ 输出 => 符合预期

---task start---
切片:aa,bb
request: aa
request: bb
wait: 2000s
切片:cc,dd
request: cc
request: dd
wait: 2000s
切片:ee,ff
request: ee
request: ff
wait: 2000s
切片:gg,hh
request: gg
request: hh
wait: 2000s 
---task over---

@teefing
Copy link

teefing commented Mar 17, 2021

code

const changeName = (name) => new Promise((resolve, reject) => {
  setTimeout(() => resolve(name), 1000)
})

const sleep = time => new Promise((resolve, reject) => {
  setTimeout(resolve, time)
})

const slicePostTask = async (names, chunkSize, time) => {
  if(names.length === 0) {
    console.log('task finish')
    console.timeEnd('slice')
    return
  }
  const tasks = names.splice(0, chunkSize)
  let tasksRes = await Promise.all(tasks.map(changeName))
  console.log('tasksRes: ', tasksRes);
  console.log(`waiting ${time/1000}s`)
  await sleep(time)
  return slicePostTask(names, chunkSize, time)
}

console.time('slice')
slicePostTask(['aa', 'bb', 'cc', 'dd', 'ee', 'ff', 'gg', 'hh'], 2, 2000)

result

tasksRes:  [ 'aa', 'bb' ]
waiting 2s
tasksRes:  [ 'cc', 'dd' ]
waiting 2s
tasksRes:  [ 'ee', 'ff' ]
waiting 2s
tasksRes:  [ 'gg', 'hh' ]
waiting 2s
task finish
slice: 12030.771ms

@kevinxft
Copy link

const changeName = (name) => new Promise((resolve, reject) => {
  setTimeout(() => resolve(name), 1000)
})

const sleep = time => new Promise((resolve, reject) => {
  setTimeout(resolve, time)
})

const slicePostTask = async (names, chunkSize, time) => {
  // todo
  const len = names.length
  let start = 0
  while (true) {
    const res = await Promise.all(names.slice(start, start + chunkSize).map(changeName))
    console.log(res)
    start += chunkSize
    if (start >= len) {
      return
    }
    console.log(`waiting ${time / 1000}s`)
    await sleep(time)
  }

}

slicePostTask(['aa', 'bb', 'cc', 'dd', 'ee', 'ff', 'gg', 'hh'], 2, 2000)

@weiChow
Copy link

weiChow commented Mar 17, 2021

const changeName = (name) => new Promise((resolve, reject) => {
  setTimeout(() => resolve(name), 1000)
})

const sleep = time => new Promise((resolve, reject) => {
  console.log('waiting 2s');
  setTimeout(resolve, time)
})

const slicePostTask = async (names, chunkSize, time) => {
  const _chunk = names.slice(0, chunkSize);

  names.splice(0, chunkSize);

  const _nextName = await Promise.all(_chunk.map((name) => changeName(name)))
  console.log(_nextName);

  if (names.length) {
    await sleep(time);

    slicePostTask(names, 2, 2000);
  } else {
    console.log('done');
  }
}

slicePostTask(['aa', 'bb', 'cc', 'dd', 'ee', 'ff', 'gg', 'hh'], 2, 2000);

@Talljack
Copy link

/*
 * 对一个很长的名字数组,做分片更新名字请求:
 * 1. 分片里的更新是并行的,执行 changeName
 * 2. 各个分片间是串行的,执行 sleep
 * 这个函数接受三个参数,名字列表、分片数量,每次分片后的等待时间
 * 比如:
 * slicePostTask(['aa', 'bb', 'cc', 'dd', 'ee', 'ff', 'gg', 'hh'], 2, 2000)
 * // => ['aa', 'bb']
 * waiting 2s
 * // => ['cc', 'dd']
 * waiting 2s
 * // => ['ee', 'ff']
 * waiting 2s
 * // => ['gg', 'hh']
 */

const changeName = (name) => new Promise((resolve, reject) => {
  console.log('name: ', name)
  setTimeout(() => resolve(name), 1000)
})

const sleep = time => new Promise((resolve, reject) => {
  console.log('wait ->>', time)
  setTimeout(resolve, time)
})

const arr = ['aa', 'bb', 'cc', 'dd', 'ee', 'ff', 'gg', 'hh']

const slicePostTask = async (names, chunkSize, time) => {
  if (!names || names.length === 0) {
    return;
  }
  const nowChunk = names.slice(0, chunkSize)
  await Promise.all(nowChunk.map(changeName))
  await sleep(time)
  return slicePostTask(names.slice(chunkSize, names.length), chunkSize, time)
}

slicePostTask(arr, 2, 2000)

@vandvassily
Copy link

/*
 * 对一个很长的名字数组,做分片更新名字请求:
 * 1. 分片里的更新是并行的,执行 changeName
 * 2. 各个分片间是串行的,执行 sleep
 * 这个函数接受三个参数,名字列表、分片数量,每次分片后的等待时间
 * 比如:
 * slicePostTask(['aa', 'bb', 'cc', 'dd', 'ee', 'ff', 'gg', 'hh'], 2, 2000)
 * // => ['aa', 'bb']
 * waiting 2s
 * // => ['cc', 'dd']
 * waiting 2s
 * // => ['ee', 'ff']
 * waiting 2s
 * // => ['gg', 'hh']
 */

const changeName = (name) =>
    new Promise((resolve, reject) => {
        setTimeout(() => resolve(name), 1000);
    });

const sleep = (time) =>
    new Promise((resolve, reject) => {
        setTimeout(resolve, time);
    });

const slicePostTask = async (names, chunkSize, time) => {
    const startTime = new Date().getTime();
    const nums = Math.ceil(names.length / chunkSize);
    for (let i = 0; i < nums; i++) {
        const name = names.slice(i * 2, (i + 1) * 2);
        changeName(name).then((res) => {
            console.log(res);
        });
        const res = await sleep(time);
        console.log(new Date().getTime() - startTime);
    }
};

slicePostTask(['aa', 'bb', 'cc', 'dd', 'ee', 'ff', 'gg', 'hh'], 2, 2000);

// ["aa", "bb"]
// 2000
// ["cc", "dd"]
// 4002
// ["ee", "ff"]
// 6003
// ["gg", "hh"]
// 8003

@SunshineZJJ
Copy link

onst changeName = (name) => new Promise((resolve, reject) => {
			  setTimeout(() => resolve(name), 1000)
			})
			
			const sleep = time => new Promise((resolve, reject) => {
			  setTimeout(resolve, time)
			})
			
			const slicePostTask = async (names, chunkSize, time) => {
			  let num=Math.ceil(names.length/chunkSize);
			  let index=0;
				 reduce(names,time,0,num,chunkSize)
			 }
			 const reduce = (names,time,i,num,chunkSize) =>{
				 changeName(names.slice(chunkSize*i,chunkSize*i+chunkSize)).then(res=>{
				 		console.log(res," ===changeName");
				 		sleep(time).then(()=>{
				 				console.log("waiting "+time+"ms");
						  if(i<num-1){
							reduce(names,time,i+1,num,chunkSize)
						  }else{
							  console.log("end-----------------");
						  }
				 		})
				  })
			 }````

@adam-zhou
Copy link

adam-zhou commented Mar 17, 2021

const changeName = (name)=> new Promise((resolve, reject)=> {
    setTimeout(()=> resolve(name), 2000)
})

const sleep = time => new Promise((resolve, reject)=> {
    setTimeout(resolve, time)
})

const slicePostTask = async (names, chunkSize, time)=> {
    let start = 0;
    let end = start + chunkSize;
    
    for(let i = 0; i < names.length/chunkSize; i++) {
        let chunk = names.slice(start, end);
        let chunkAsyncRes = await Promise.all(chunk.map(async (name)=> {
            return await changeName(name);
        }))
        console.log(chunkAsyncRes);
        
        await sleep(time);
        start = end;
        end = start + chunkSize;
    }
}
// 方法二 递归
//const slicePostTask = async (names, chunkSize, time) => {
//    if(!names.length || chunkSize === 0) return;
//    let chunk = names.slice(0, chunkSize);
//    let chunkAsyncRes = await Promise.all(chunk.map(async (name)=> {
//        return await changeName(name);
//    }))
//    console.log(chunkAsyncRes);
//    await sleep(time);
//    return slicePostTask(names.slice(chunkSize), chunkSize, time)
}

slicePostTask(['aa', 'bb', 'cc', 'dd', 'ee', 'ff', 'gg', 'hh'], 3, 4000)

@BillScott1024
Copy link

/**
 * Desc: 数据排重

 * 对一个很长的名字数组,做分片更新名字请求:
 * 1. 分片里的更新是并行的,执行 changeName
 * 2. 各个分片间是串行的,执行 sleep
 * 这个函数接受三个参数,名字列表、分片数量,每次分片后的等待时间
 * 比如:
 * slicePostTask(['aa', 'bb', 'cc', 'dd', 'ee', 'ff', 'gg', 'hh'], 2, 2000)
 * // => ['aa', 'bb']
 * waiting 2s
 * // => ['cc', 'dd']
 * waiting 2s
 * // => ['ee', 'ff']
 * waiting 2s
 * // => ['gg', 'hh']

const changeName = (name) => new Promise((resolve, reject) => {
    setTimeout(() => resolve(name), 1000)
  })

  const sleep = time => new Promise((resolve, reject) => {
    setTimeout(resolve, time)
  })

  const slicePostTask = async (names, chunkSize, time) => {
    // todo
  }
 * */


const changeName = (name: string) => new Promise((resolve, reject) => {
    console.log(`changeName... ${name}`);
    setTimeout(() => resolve(name), Math.random() * 1000)
})

const sleep = (time: number) => new Promise((resolve, reject) => {
    console.log(`waiting... ${time}`);
    setTimeout(resolve, time)
})

const slicePostTask = async (names: string[], chunkSize: number, time: number) => {
    // todo
    if (!names || names.length == 0) {
        return null;
    }

    const chunkSubArray = names.splice(0, chunkSize);
    const changedNamesTask = [];
    for (let index = 0; index < chunkSubArray.length; index++) {
        const chunkName = chunkSubArray[index];
        changedNamesTask.push(changeName(chunkName));
    }
    const resultArray = await Promise.all(changedNamesTask);
    console.log(`=> ${JSON.stringify(resultArray)}`)
    await sleep(time);
    return slicePostTask(names, chunkSize, time);

}
console.log("start!");

slicePostTask(['aa', 'bb', 'cc', 'dd', 'ee', 'ff', 'gg', 'hh'], 2, 2000);

image

Edit adoring-swirles-xmcef

@docterlei
Copy link

docterlei commented Mar 17, 2021

const changeName = (name) => new Promise((resolve, reject) => {
    setTimeout(() => resolve(name), 1000)
  })
  
  const sleep = time => new Promise((resolve, reject) => {
    setTimeout(resolve, time)
  })
  
  const slicePostTask = async (names, chunkSize, time) => {
      const queue = []
      while(names.length) {
          queue.unshift(changeName(names.splice(0,chunkSize)))
      }
     const run = async (arr) => {
         if(arr.length) {
            const res = await queue[queue.length - 1];
            console.log(res)
            queue.pop()
            await sleep(time)
            run(arr)
         }
         return null
     }
   run(queue)
  }

  slicePostTask(['aa', 'bb', 'cc', 'dd', 'ee', 'ff', 'gg', 'hh'], 2, 2000)

@dorothyLee56
Copy link

const changeName = (name) =>
  new Promise((resolve, reject) => {
    setTimeout(() => resolve(name), 1000);
  });

const sleep = (time) =>
  new Promise((resolve, reject) => {
    setTimeout(resolve, time);
  });

const slicePostTask = async (names, chunkSize, time) => {
  // todo
  if (!names.length || chunkSize === 0) return;

  for (let i = 0; i < names.length; i += chunkSize) {
    let chunkNames = names.slice(i, i + chunkSize);
    await Promise.all(chunkNames.map((name) => changeName(name))).then((res) =>
      console.log(res)
    );
    console.log(`waiting ${time}ms`);
    await sleep(time);
  }
};

slicePostTask(["aa", "bb", "cc", "dd", "ee", "ff", "gg", "hh"], 2, 2000);

@yang-1234
Copy link

   const changeName = (name) => new Promise((resolve, reject) => {
        setTimeout(() => {
            console.log(name)
            resolve(name)
        }, 1000)
    })
    const sleep = time => new Promise((resolve, reject) => {
        console.log(`waiting ${time / 1000}s`)
        setTimeout(resolve, time)
    })
    const slicePostTask = async (names, chunkSize, time) => {
        if (!names || !names.length) return
        for (let i = 0; i < names.length; i += 2) {
            await changeName(names.slice(i, i + 2))
            await sleep(2000)
        }
    }
    slicePostTask(['aa', 'bb', 'cc', 'dd', 'ee', 'ff', 'gg', 'hh'], 2, 2000)

@huahua5525
Copy link

const changeName = (name) => new Promise((resolve, reject) => {
  setTimeout(() => {
    console.log('changeName: ', name);
    resolve(name)
  }, 1000)
})

const sleep = time => new Promise((resolve, reject) => {
  console.log('sleep', time)
  setTimeout(resolve, time)
})

const slicePostTask = async (names, chunkSize, time) => {
  // todo
  if (!names || names.length < 1) return
  const sliceResult = names.slice(0, chunkSize)
  await changeName(sliceResult)
  await sleep(time)
  slicePostTask(names.slice(chunkSize), chunkSize, time) 
}
slicePostTask(['aa', 'bb', 'cc', 'dd', 'ee', 'ff', 'gg', 'hh'], 2, 2000)

结果
image

@free-qiaochen
Copy link

const changeName = (name) => new Promise((resolve, reject) => {
  setTimeout(() => resolve(name), 1000)
})

const sleep = time => new Promise((resolve, reject) => {
  setTimeout(resolve, time)
})

const slicePostTask = async (names, chunkSize, time) => {
  // todo
  if (names.length<=0) {
    return
  }
  var nums = chunkSize
  var target = []
  while(nums){
    nums--
    target.push(names.shift(0))
  }
  console.log(target,names)
  await sleep(time)
  slicePostTask(names, chunkSize, time)
}
slicePostTask(['aa', 'bb', 'cc', 'dd', 'ee', 'ff', 'gg', 'hh'], 2, 2000)

@mengzhe510
Copy link

const changeName = (name) => new Promise((resolve, reject) => {
  setTimeout(() => resolve(name), 1000)
})

const sleep = time => new Promise((resolve, reject) => {
  setTimeout(resolve, time)
})

const slicePostTask = async (names, chunkSize, time) => {
  if (!names || !names.length) {
    return null
  }
  let t = new Date().getSeconds()
  console.log(`start:${t}s`)
  while (names.length) {
    await sleep(time).then(
      await Promise.all(names.splice(0, chunkSize).map(item => changeName(item))).then(data => {
        console.log(`=>`, data)
      })
    )
    let timenow = new Date().getSeconds()
    const _time = timenow - t
    console.log(`wait:${_time}s`)
    t = timenow
  }
}
slicePostTask(['aa', 'bb', 'cc', 'dd', 'ee', 'ff', 'gg', 'hh'], 2, 2000)


@panalanjun
Copy link

const changeName = (name) => new Promise((resolve, reject) => {
  setTimeout(() => resolve(name), 1000)
})

const sleep = time => new Promise((resolve, reject) => {
  console.log("waiting", time / 1000 + 's');
  setTimeout(resolve, time)
})

const slicePostTask = async (names, chunkSize, time) => {
  // todo
  var index = 0;	// 记录切割数组的下标

  for (var i = 0; i < Math.ceil(names.length / chunkSize); i++) {
  	var res = await changeName(names.slice(index, index + chunkSize));
  	index += chunkSize;
  	console.log(res);
  	await sleep(time);
  }
}

slicePostTask(['aa', 'bb', 'cc', 'dd', 'ee', 'ff', 'gg', 'hh'], 2, 2000);

@GeekNoble
Copy link

const changeName = (name) => new Promise((resolve, reject) => {
setTimeout(() => {
console.log("name", name)
resolve(name)
}, 1000)
})

const sleep = time => new Promise((resolve, reject) => {
  setTimeout(() => {
    console.log('waiting', time)
    resolve()
  }, time)
})

const slicePostTask = async (names, chunkSize, time) => {
  if (!names.length) {
    return
  }
  let arr = names.splice(0, chunkSize), task = []
  arr.forEach(item => {
    task.push(changeName(item))
  });
  await Promise.all(task)
  await sleep(time)
  return slicePostTask(names, chunkSize, time)
}
slicePostTask(['aa', 'bb', 'cc', 'dd', 'ee', 'ff', 'gg', 'hh'], 2, 2000)

@Ecaknight
Copy link

  const changeName = (name) => new Promise((resolve, reject) => {
    setTimeout(() => resolve(name), 1000)
  })

  const sleep = time => new Promise((resolve, reject) => {
    setTimeout(resolve, time)
  })

  const slicePostTask = async (names, chunkSize, time) => {
    const arr = Array.from(names)
    while (arr.length) {
      const chunk = arr.splice(0, chunkSize)
      const fetchArr = chunk.map(v => changeName(v))
      const res = await Promise.all(fetchArr)
      console.log(res)
      await sleep(time)
      console.log('waiting ' + Math.floor(time / 1000)  + 's')
    }
  }
  slicePostTask(['aa', 'bb', 'cc', 'dd', 'ee', 'ff', 'gg', 'hh'], 2, 2000)

@Leexuetao
Copy link

/*

  • 对一个很长的名字数组,做分片更新名字请求:
    1. 分片里的更新是并行的,执行 changeName
    1. 各个分片间是串行的,执行 sleep
  • 这个函数接受三个参数,名字列表、分片数量,每次分片后的等待时间
  • 比如:
  • slicePostTask(['aa', 'bb', 'cc', 'dd', 'ee', 'ff', 'gg', 'hh'], 2, 2000)
  • // => ['aa', 'bb']
  • waiting 2s
  • // => ['cc', 'dd']
  • waiting 2s
  • // => ['ee', 'ff']
  • waiting 2s
  • // => ['gg', 'hh']
    */

const changeName = (name) => new Promise((resolve, reject) => {
setTimeout(() => resolve(name), 1000)
})

const sleep = time => new Promise((resolve, reject) => {
setTimeout(resolve, time)
})

const slicePostTask = async (names, chunkSize, time) => {
while(names.length) {
const current = names.splice(0, chunkSize)
await Promise.all(current.map(changeName)).then((name) => {
console.log(name)
})
await sleep(time)
}
}

@huangpingcode
Copy link

const changeName = (name) => new Promise((resolve, reject) => {
  setTimeout(() => resolve(name), 1000)
})

const sleep = time => new Promise((resolve, reject) => {
  setTimeout(resolve, time)
})

const slicePostTask = async (names, chunkSize, time) => {
  for(let i = 0, max = names.length; i < max; i += chunkSize){
    let temp = names.slice(i, i+chunkSize).map(name => changeName(name))
    temp.unshift(i === 0 ? () => null : sleep(2000))
    let [,...res] = await Promise.all(temp)
    console.log(res);
  }
}
slicePostTask(['aa', 'bb', 'cc', 'dd', 'ee', 'ff', 'gg', 'hh'], 2, 2000)

@sunsmeil
Copy link

/*
 * 对一个很长的名字数组,做分片更新名字请求:
 * 1. 分片里的更新是并行的,执行 changeName
 * 2. 各个分片间是串行的,执行 sleep
 * 这个函数接受三个参数,名字列表、分片数量,每次分片后的等待时间
 * 比如:
 * slicePostTask(['aa', 'bb', 'cc', 'dd', 'ee', 'ff', 'gg', 'hh'], 2, 2000)
 * // => ['aa', 'bb']
 * waiting 2s
 * // => ['cc', 'dd']
 * waiting 2s
 * // => ['ee', 'ff']
 * waiting 2s
 * // => ['gg', 'hh']
 */
/**
** 1. 对数组进行分片
** 2. 异步 并行和串行
**/
const changeName = (name) => new Promise((resolve, reject) => {
  setTimeout(() => resolve(name), 1000)
  console.log('并行打印', name)
})

const sleep = time => new Promise((resolve, reject) => {
  setTimeout(resolve, time)
  console.log('串行打印', time)
})

const slicePostTask = async (names, chunkSize, time) => {
  // 数组分片
  if(names.length === 0){
    return
  }
  let splNames = names.splice(0, chunkSize)
  
  await Promise.all(splNames.map(changeName))
  await sleep(time)
  slicePostTask(names, chunkSize, time)
}
slicePostTask(['aa', 'bb', 'cc', 'dd', 'ee', 'ff', 'gg', 'hh'], 2, 3000)

@learnRy
Copy link

learnRy commented Mar 17, 2021

const changeName = (name) => new Promise((resolve, reject) => {
  setTimeout(() => {
    console.log(name)
    resolve(name)
  }, 100)
})

const sleep = time => new Promise((resolve, reject) => {
  setTimeout(resolve, time)
})

const slicePostTask = async (names, chunkSize, time) => {
  for(let i = 0; i < (names.length + 1)/ chunkSize; i++) {
    await Promise.all(names.slice(i * chunkSize, (i + 1) * chunkSize).map(item => changeName(item)))
    await sleep(time)
  }
  
}

@chen870370470
Copy link

const changeName = (name) =>
  new Promise((resolve, reject) => {
    setTimeout(() => resolve(name), 1000);
  });

const sleep = (time) =>
  new Promise((resolve, reject) => {
    setTimeout(resolve, time);
  });

const slicePostTask = async (names, chunkSize, time) => {
  if (!names.length) {
    return;
  }
  const reqArr = names.length < chunkSize ? names : names.slice(0, chunkSize);
  await changeName(reqArr).then((res) => {
    console.log(res);
    if (reqArr.length === names.length) {
      return;
    }
    console.log(`wating${time / 1000}s`);
  });
  await sleep(time);
  slicePostTask(names.slice(chunkSize, names.length), chunkSize, time);
};
slicePostTask(["aa", "bb", "cc", "dd", "ee", "ff", "gg", "hh"], 2, 2000);

@AbigaiL533
Copy link

const changeName = (name) => new Promise((resolve, reject) => {
  setTimeout(() => resolve(name), 1000)
})

const sleep = time => new Promise((resolve, reject) => {
	console.log(`${time/1000}s`)
  setTimeout(resolve, time)
})

const slicePostTask = async (names, chunkSize, time) => {
  if(names.length){
  	const result = await Promise.all(names.slice(0, chunkSize).map(changeName));
    console.log('// => ', result);
    await sleep(time);
    return slicePostTask(names.slice(chunkSize), chunkSize, time)
  }
}

slicePostTask(['aa', 'bb', 'cc', 'dd', 'ee', 'ff', 'gg', 'hh'], 2, 2000)

@goldEli
Copy link

goldEli commented Mar 18, 2021

const changeName = (name) =>
  new Promise((resolve, reject) => {
    setTimeout(() => resolve(name), 1000);
  });

const sleep = (time) =>
  new Promise((resolve, reject) => {
    setTimeout(resolve, time);
  });

const slicePostTask = async (names, chunkSize, time) => {
  if (names.length === 0) return;
  Promise.all(names.slice(0, chunkSize).map((name) => changeName(name))).then(
    async (data) => {
      console.log(data);
      await sleep(2000);
      slicePostTask(names.slice(chunkSize), chunkSize, time);
    }
  );
};
slicePostTask(["aa", "bb", "cc", "dd", "ee", "ff", "gg", "hh"], 2, 2000);

@makejun168
Copy link

方法一

处理数组每次输出两个片段,然后 await sleep
利用递归再执行多一次函数

const changeName = (name) => new Promise((resolve, reject) => {
  setTimeout(() => resolve(name), 1000)
})

const sleep = time => new Promise((resolve, reject) => {
  setTimeout(resolve, time)
})

const slicePostTask = async (names, chunkSize, time) => {
		if (!names.length) {
			console.log('finish');
			return 0
		}
    await changeName(names.splice(0, chunkSize));
		await sleep(time)
		return slicePostTask(names, chunkSize, time)
}

console.time()
slicePostTask(['aa', 'bb', 'cc', 'dd', 'ee', 'ff', 'gg', 'hh'], 2, 2000)
console.timeEnd()

@mingyuesun
Copy link

const changeName = (name) => new Promise((resolve, reject) => {
  setTimeout(() => resolve(name), 1000)
})

const sleep = time => new Promise((resolve, reject) => {
  console.log(`waiting ${time/1000}s`)
  setTimeout(resolve, time)
})

const slicePostTask = async (names, chunkSize, time) => {
  // todo
  const chunk = await Promise.all(names.slice(0, chunkSize).map(name =>  changeName(name)))
  console.log(chunk)
  if (names.length > chunkSize) {
    await sleep(time)
    slicePostTask(names.slice(chunkSize), chunkSize, time)
  }
}
		
slicePostTask(['aa', 'bb', 'cc', 'dd', 'ee', 'ff', 'gg', 'hh'], 3, 2000)

/**
 * ["aa", "bb", "cc"]
 * waiting 2s
 * ["dd", "ee", "ff"]
 * waiting 2s
 * ["gg", "hh"]
 */

@muzishuiji
Copy link

// 分片请求
const changeName = (name) => new Promise((resolve, reject) => {
    setTimeout(() => {
        console.log("changeName -> name", name)
        resolve(name);
    }, 1000);
});
const sleep = time => new Promise((resolve, reject) => {
    console.log("sleep", time)
    setTimeout(resolve, time)
});

const slicePostTask = async (names, chunkSize, time) => {
    let start = 0;
    const len = names.length;
    const loop = async () => {
        const task = names.slice(start, start + chunkSize);
        await Promise.all(task.map(changeName)).then();
        start = start + chunkSize;
        if(start > len - 1) {
            console.log('finished')
            return true;
        }
        await sleep(time);
        return loop()
    }
    await loop();
}
slicePostTask(['aa', 'bb', 'cc', 'dd', 'ee', 'ff', 'gg', 'hh'], 2, 2000)

image

@huangzhuangjia
Copy link

huangzhuangjia commented Mar 29, 2021

const slicePostTask = async (names, chunkSize, time) => {
  // todo
  let i = 0;
  const run = async () => {
    const arr = await changeName(names.slice(i , i + chunkSize));
    console.log(arr);
    await sleep(time);
    i = i + chunkSize;
    if (i < names.length) {
      run();
    }
  };
  await run();
}

@xiaocongWang
Copy link

xiaocongWang commented Apr 13, 2021

const changeName = name => new Promise((resolve, reject) => {
    setTimeout(() => resolve(name), 1000);
});

const sleep = time => new Promise((resolve, reject) => {
    setTimeout(resolve, time);
});

const slicePostTask = async(names, chunkSize, time) => {
    let index = 0;

    while (index < names.length) {
        const chunkNames = names.slice(index, index + chunkSize);
        index += chunkSize;

        const promises = chunkNames.map(changeName);
        const result = await Promise.all(promises);
        console.log(result);

        await sleep(time);
    }
};

@pumpkin123
Copy link

/*
 * 对一个很长的名字数组,做分片更新名字请求:
 * 1. 分片里的更新是并行的,执行 changeName
 * 2. 各个分片间是串行的,执行 sleep
 * 这个函数接受三个参数,名字列表、分片数量,每次分片后的等待时间
 * 比如:
 * slicePostTask(['aa', 'bb', 'cc', 'dd', 'ee', 'ff', 'gg', 'hh'], 2, 2000)
 * // => ['aa', 'bb']
 * waiting 2s
 * // => ['cc', 'dd']
 * waiting 2s
 * // => ['ee', 'ff']
 * waiting 2s
 * // => ['gg', 'hh']
 */

const changeName = name =>
  new Promise((resolve, reject) => {
    setTimeout(() => resolve(name), 1000);
  });

const sleep = time =>
  new Promise((resolve, reject) => {
    setTimeout(resolve, time);
  });

function chunk(arr, size) {
  if (!Array.isArray(arr) || !size) {
    return [];
  }
  const res = [];
  for (let i = 0; i < arr.length; i += size) {
    res.push(arr.slice(i, i + size));
  }
  return res;
}

const slicePostTask = async (names, chunkSize, time) => {
  // todo
  const chunkArr = chunk(names, chunkSize);
  for (let i = 0; i < chunkArr.length; i += 1) {
    await Promise.all(chunkArr[i].map(item => changeName(item)));
    await sleep(time);
  }
};

slicePostTask(['aa', 'bb', 'cc', 'dd', 'ee', 'ff', 'gg', 'hh'], 2, 2000);

@KieSun KieSun closed this as completed Sep 16, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests