zhuanghaixin / Interview

8 stars 0 forks source link

利用平行执行 #224

Open zhuanghaixin opened 2 years ago

zhuanghaixin commented 2 years ago
async function randomDelay(id) {
    const delay = Math.random() * 1000
    return new Promise((resolve)=>setTimeout(()=>{
        console.log(`${id} finished  ${delay}`)
        resolve()
    }
    , delay))
}

async function foo(){
    const t0= Date.now()
    await randomDelay(0)
    await randomDelay(1)
    await randomDelay(2)
    await randomDelay(3)
    await randomDelay(4)
    console.log(`${Date.now()-t0} ms elapsed}`)
}

foo()

用一个for循环重写,就是:

async function randomDelay(id) {
    const delay = Math.random() * 1000
    return new Promise((resolve)=>{
        setTimeout(()=>{
            console.log(`${id} finished  ${delay}`)
            resolve()
        }
        )
    }
    )
}

async function foo(){
    const t0= Date.now()
    for (let i = 0; i < 5; i++) {
         await randomDelay(i)    
    }
    console.log(`${Date.now()-t0} ms elapsed}`)
}
foo()

就算这些期约之间没有依赖,异步函数也会依次暂停,等待每个超时完成。这样可以保证执行顺序,但总执行时间会变长。如果顺序不是必需保证的,那么可以先一次性初始化所有期约,然后再分别等待它们的结果。比如:

async function randomDelay(id) {
  // 延迟0~1000 毫秒
  const delay = Math.random() * 1000;
  return new Promise((resolve) => setTimeout(() => {
    setTimeout(console.log, 0, `${id} finished`);
    resolve();
  }, delay));
}
async function foo() {
  const t0 = Date.now();
  const p0 = randomDelay(0);
  console.log('p0',p0)
  const p1 = randomDelay(1);
  console.log('p1',p1)
  const p2 = randomDelay(2);
  console.log('p2',p2)
  const p3 = randomDelay(3);
  console.log('p3',p3)
  const p4 = randomDelay(4);
  console.log('p4',p4)
  await p0;
  await p1;
  await p2;
  await p3;
  await p4;
  setTimeout(console.log, 0, `${Date.now() - t0}ms elapsed`);
}
foo();
// 1 finished
// 4 finished
// 3 finished
// 0 finished
// 2 finished
// 877ms elapsed

这里有点不清楚 for循环包装

async function randomDelay(id) {
    // 延迟0~1000 毫秒
    const delay = Math.random() * 1000;
    return new Promise((resolve)=>setTimeout(()=>{
        console.log(`${id} finished`);
        resolve();
    }
    , delay));
}
async function foo() {
    const t0 = Date.now();
    const promises = Array(5).fill(null).map((_,i)=>randomDelay(i));
    console.log('promises',promises)
    for (const p of promises) {
        await p;
    }
    console.log(`${Date.now() - t0}ms elapsed`);
}
foo()

上面两个都是先一次性初始化所有期约