javascript - 如何保证多个 promise 的解决顺序?

标签 javascript promise ecmascript-6 es6-promise

尝试学习一些现代 JS,尤其是 ECMAScript 6 Promises。我正在玩这个简单的测试:

let slow = new Promise((resolve) => {
  setTimeout(function()
  {  
	console.log('slow');
	resolve();	
  }, 2000, 'slow');
});

let instant = new Promise((resolve) => {
	console.log('instant');
	resolve();	
});

let quick = new Promise((resolve) => {
  setTimeout(function()
  {  
	console.log('quick');
	resolve();	
  }, 1000, 'quick');
});

Promise.all([slow, instant, quick]).then(function(results) {
  console.log('finished');
}, function(error) {
  console.log(error);	
});

我在这里想要的是同时启动所有的 Promises 异步。并在它们全部完成时记录下来。在控制台中,这按预期显示:“即时”、“快速”、“慢速”和“完成”。

但是,如果我想确保“instant”在“slow”完成之前不回显/记录怎么办?也就是说,我希望控制台记录“快速”、“慢速”、“即时”和“完成”……但同时,它们仍必须同时异步启动。

我怎样才能做到这一点?

最佳答案

所以要明确一点,您想在这里做的是立即启动所有 promise ,并在每个 promise 的结果进入时以特定顺序显示它们,对吗?

在那种情况下,我可能会这样做:

let slow = new Promise((resolve) => {
  setTimeout(function()
  {
    // Rather than log here, we resolve to the value we want to log
    resolve('slow');
  }, 2000, 'slow');
});

let instant = new Promise((resolve) => {
    resolve('instant');  
});

let quick = new Promise((resolve) => {
  setTimeout(function()
  {  
    resolve('quick');  
  }, 1000, 'quick');
});

// All Promises are now running. Let's print the results...

// First wait for the result of `slow`...
slow.then((result) => {
  // Result received...
  console.log(result);
  
  // Now wait for the result of instant...
  instant.then((result) => {
    
    // Result received...
    console.log(result);
    
    // Now wait for the result of quick...
    quick.then((result) => {
      
      // Result received...
      console.log(result);
      
    }).then((result) => {
      // Done
      console.log('finished');
    });
  });
});

请注意,与 cchamberlain 不同的 answer ,此方法不会在开始返回结果之前等待所有 promise 解决。它返回结果,但不会违反保持结果有序的要求。 (要验证这一点,请尝试将 quick 的等待时间更改为 2500 毫秒,并观察其结果在 instant 后 500 毫秒打印。)根据您的应用程序,这可能是理想的.

上面的代码有点乱,但幸好有了 ES2017 中新的 async/await 语法,它可以变得更清晰:

let slow = new Promise((resolve) => {
  setTimeout(function()
  {
    // Rather than log here, we resolve to the value we want to log
    resolve('slow');
  }, 2000, 'slow');
});

let instant = new Promise((resolve) => {
    resolve('instant');  
});

let quick = new Promise((resolve) => {
  setTimeout(function()
  {  
    resolve('quick');  
  }, 1000, 'quick');
});

// All Promises are now running. Let's print the results...

async function logResults(...promises) {
  for (let promise of promises) {
    console.log(await promise);
  }
}

logResults(slow, instant, quick).then(() => console.log('finished'));

Try in Babel .注意:以上代码目前无法在没有 Babel 的现代浏览器中运行(截至 2016 年 10 月)。在未来的浏览器中它会。

关于javascript - 如何保证多个 promise 的解决顺序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40248023/

相关文章:

javascript - jquery中的get()和eq()有什么区别?

javascript - ref.current.focus() 不是函数

javascript - 当 Promise 状态被拒绝或解决时

javascript - 使用 JavaScript 循环两个数组

javascript - 如何在 sails.js 0.10 中接收套接字事件?

javascript - 为什么 pre 标签后的换行符消失了?

javascript - Promise.all 中的索引

javascript - 为什么这是未处理的 promise 拒绝?

javascript - ES6 : fire React function

javascript - 为什么 const 在 JavaScript 中的某些 for 循环中有效?