我如何保证多个承诺的解决方案顺序?

Wer*_*ner 5 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);	
});
Run Code Online (Sandbox Code Playgroud)

我想要的是同时启动所有Promise异步.并在完成后记录.在控制台中,它按预期显示:"即时","快速","慢速"和"完成".

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

我怎样才能做到这一点?

Aje*_*i32 4

因此,需要明确的是,您想要在这里做的是立即启动所有 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');
    });
  });
});
Run Code Online (Sandbox Code Playgroud)

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

上面的代码有点混乱,但幸运的是,使用async/awaitES2017 中的新语法,它可以变得更加清晰:

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'));
Run Code Online (Sandbox Code Playgroud)

尝试巴别塔。注意:上述代码目前无法在没有 Babel 的现代浏览器中运行(截至 2016 年 10 月)。在未来的浏览器中它会的。