首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >使用Promise.all()在履行承诺时执行操作

使用Promise.all()在履行承诺时执行操作
EN

Stack Overflow用户
提问于 2016-09-27 23:35:30
回答 2查看 1.5K关注 0票数 17

我可以使用Promise.all(array)异步解析一堆promises。然而,只有在所有这些承诺都得到解决之后,.then()才会运行。当承诺得到解决时,我如何执行操作?

例如,我希望使用Promise.all()异步加载一篇文章中的所有段落-这样,网络请求就可以一次触发。如果段落1加载完成,我希望它呈现到页面上-但只有在段落2之前完成加载时,我才希望加载段落2。如果段落3已经加载完成,而2没有加载,我希望3在渲染到页面之前等待2。诸若此类。

我试过这样的东西,但我不知道下一步该做什么:

代码语言:javascript
复制
var getStuff = function(number, time){
  return new Promise(function(resolve, reject){
    window.setTimeout(function(){resolve(`${number} - Done.`)}, time);
  });
};

Promise.all([ getStuff(1, 200),
              getStuff(2, 100),
              getStuff(3, 250),
              getStuff(4, 200),
              getStuff(5, 300),
              getStuff(6, 250),
              getStuff(7, 5000)])
.then(function(data){
  console.log(data);
});

我如何才能获得一个接一个数据的控制台日志-而不是在发出下一个请求之前使用then()解析每个promise?有没有更好的方法来做这件事?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-09-27 23:43:45

您不能使用Promise.all实现此顺序,因为从Promise.all返回的promise会等待所提供的数组中的所有promise并行解析(而不是顺序解析),然后才会自动解析。

相反,您可以同时单独创建其请求的promises和fire:

代码语言:javascript
复制
// create promises and make concurrent requests
const s1 = getStuff(1, 200);
const s2 = getStuff(2, 100);
const s3 = getStuff(3, 250);
// ...

然后创建一个关于如何处理它们的反应链(stuff1先于stuff2,stuff2先于stuff3,等等)

代码语言:javascript
复制
// create a chain of reaction order to the results of parallel promises
s1
  .then(console.log) // s1 resolved: log result
  .then(() => s2)    // chain s2
  .then(console.log) // s2 resolved: log result
  .then(() => s3)    // chain s3
  // ...
  .then(() => {      // chain another function at at the end for when all promises resolved
    // all promises resolved (all data was logged)
  }

要以创建promise的相同顺序对promise结果做出反应,可以使用Array.prototype.reduce更改getStuff函数以动态地链接这些反应

代码语言:javascript
复制
var times = [200, 100, 250, 200, 300, 250, 5000];

var getStuff = function(time, index) { // swap the order of arguments so number is the index passed in from Array.map
  return new Promise((resolve, reject) => {
    window.setTimeout(() => {
      resolve(`${index + 1} - Done.`); // use index + 1 because indexes start at 0
    }, time);
  });
};

times
  // map each time to a promise (and number to the index of that time + 1) and fire of a request
  .map(getStuff)
  // dynamically build a reaction chain for the results of promises
  .reduce((chain, promise) => {
    return chain
      .then(() => promise)
      .then(console.log);
  }, Promise.resolve())
  .then(() => {
    // all promises resolved (all data was logged in order)
  });

票数 18
EN

Stack Overflow用户

发布于 2016-09-27 23:44:20

我知道它不是原生的,但使用bluebird,您可以使用Promise.some (在count承诺完成后完成)或Promise.mapSeries (连续完成承诺)以某种方式实现您期望的流程。

Bluebird API

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39728793

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档