Ecmascript 6 使用Promise.all时承诺之间的延迟

Ecmascript 6 使用Promise.all时承诺之间的延迟,ecmascript-6,promise,Ecmascript 6,Promise,有没有办法使用Promise.all()延迟对承诺数组的求值 在将每个承诺添加到数组之前,手动将延迟函数添加到每个承诺的末尾有意义吗 Promise.all([p1,p2,p3]).then(res => console.log(res)) 我想增加一个延迟,因为我的服务器不能同时处理太多的请求 有没有一种方法可以延迟使用 Promise.all() 不。承诺不是“被评估的”,它们只是解决问题。这一切发生的时间取决于他们的创造者,而不是别的。调用Promise.all时,promises

有没有办法使用Promise.all()延迟对承诺数组的求值

在将每个承诺添加到数组之前,手动将延迟函数添加到每个承诺的末尾有意义吗

Promise.all([p1,p2,p3]).then(res => console.log(res))
我想增加一个延迟,因为我的服务器不能同时处理太多的请求

有没有一种方法可以延迟使用
Promise.all()


不。承诺不是“被评估的”,它们只是解决问题。这一切发生的时间取决于他们的创造者,而不是别的。调用
Promise.all
时,promises
p1
p2
p3
已经创建(并且它们的异步任务可能已经启动)。

Promise.all
旨在解决承诺何时实现的问题,但现有承诺的评估与
承诺无关。所有

为了做到这一点,最初应创建承诺以产生延迟:

const delayIncrement = 500;
let delay = 0;

const p1 = new Promise(resolve => setTimeout(resolve, delay)).then(() => fetch(...));

delay += delayIncrement;

const p2 = new Promise(resolve => setTimeout(resolve, delay)).then(() => fetch(...));

delay += delayIncrement;

...
Promise.all([p1,p2,p3]).then(...);
同样的解决方案也可用于在循环内批量创建请求承诺

可以在中找到延迟承诺的方法。

是的,您可以使用Promise.all延迟承诺。所有这些都可以创建交错执行,而且非常容易做到:

// Promise.all() with delays for each promise
let tasks = [];
for (let i = 0; i < 10; i++) {
  const delay = 500 * i;
  tasks.push(new Promise(async function(resolve) {
    // the timer/delay
    await new Promise(res => setTimeout(res, delay));

    // the promise you want delayed
    // (for example):
    // let result = await axios.get(...);
    let result = await new Promise(r => {
      console.log("I'm the delayed promise...maybe an API call!");
      r(delay); //result is delay ms for demo purposes
    });

    //resolve outer/original promise with result
    resolve(result);
  }));
}

let results = Promise.all(tasks).then(results => {
  console.log('results: ' + results);
});
//Promise.all(),每个Promise都有延迟
让任务=[];
for(设i=0;i<10;i++){
常数延迟=500*i;
推送(新承诺)(异步函数(解析){
//定时器/延迟
等待新的承诺(res=>setTimeout(res,delay));
//你想推迟的承诺
//(例如):
//让结果=等待axios.get(…);
让结果=等待新的承诺(r=>{
log(“我是延迟的承诺……可能是API调用!”);
r(delay);//出于演示目的,结果是delay ms
});
//用结果解决外部/原始承诺
决心(结果);
}));
}
让结果=承诺。所有(任务)。然后(结果=>{
console.log('results:'+results);
});
你也可以运行它

而不是链之间的延迟(如其他答案中所示,.then()可以完成),这是一个延迟,每个承诺都不同,因此当调用Promise.all()时,它们将交错。例如,当您调用一个API时,如果并行地触发所有调用,就会违反速率限制,这将非常有用


Peace

我需要动态创建呼叫,因此根据@estus flask的回答,我设法想出了:

  let delay = 0; const delayIncrement = 1000;

  const promises = items.map(item => {
    delay += delayIncrement;
    return new Promise(resolve => setTimeout(resolve, delay)).then(() =>
        fetch(...);
  })

  let results = await Promise.all(promises);

另一种方法是劫持循环的传输方式:

异步函数DOAATCHOFASYNCWORK(工作项){
用于(工作项的常量项){
等待工作任务(项目)
wait delay(1000)//不是内置的,但可以通过setTimeout+promise轻松实现
}
}

当然,您也可以保存这些值,并在最后返回它们,这与for循环中通常的做法完全相同。您不能对map执行此操作,因为等待必须位于传入的map functor的异步上下文中。如果您使用map,它将同时执行所有操作,最后延迟1s。

我认为这在代码方面无法扩展,假设我想调用100个承诺。这将导致一个很长的文件。这就是为什么我想尝试使用Promise.all()以编程方式实现它。Promise是在调用时创建的。我保证,所有通话结束后,all会通知你。这不会耽误他们。你需要实际推迟打电话,而不是承诺。这很有意义,谢谢@OriDrori。这取决于你如何实际创造所有承诺,如果您想序列化调用,您可能会对async Wait感兴趣。这与@estus flask的答案相同,但在循环中有点不同,因为它更现实。通常情况下,您必须根据事先不知道的内容进行循环。另外,它使用wait-to-block,而不是将逻辑放在setTimeout中,setTimeout并不总是有效的,特别是当你也必须在那里进行阻塞时。完美的解决方案!