从父承诺中解决一系列承诺

Posted

技术标签:

【中文标题】从父承诺中解决一系列承诺【英文标题】:resolving an array of promises from within a parent promise 【发布时间】:2016-09-02 01:34:59 【问题描述】:

这是我第一次尝试嵌套 promise。我正在使用 bluebird 库,但我认为所有 promise 库的想法都是一样的。

在高层次上,这就是我想要做的:

myService.getSomeData(url)
 .then((data) => 
   myOtherService.getMoreData(data.uniqueId)
   .then((thisDataIsAnArray) => 
      //loop over the data above and do something
   );
 );

getMoreData() 应该进行 X 服务调用并将结果存储在 X 元素长的数组中。这就是我开始迷路的地方,因为我不确定如何制作这种方法以及我应该从中返回什么。我在 bluebird 的 Promise.allPromise.map 上进行了几次尝试,但我犹豫不决,并认为我会征求建议。

【问题讨论】:

试图了解你的目标。那么,你想执行一组承诺,然后在给定第一组承诺的解决方案的情况下执行另一组承诺,然后根据第二组承诺的解决方案执行第三组逻辑? Promise 的目标之一是消除“回调地狱”。因此,链式 Promise 比嵌套 Promise 更好。 您可能希望以flattening your chain 开头。 每个异步方法都应该return一个promise来获取其中异步操作的结果。每一个。 @jpodwys 的主要思想是执行第一个承诺,获取由此产生的数据,然后执行 X 多个承诺(其中数量取决于原始结果)并将它们的结果返回到我们的数组中可以使用。 不确定您要问什么,但这可能会有所帮助:How to chain and share prior results with Promises。 【参考方案1】:

Promise 只是 返回值,您将回调附加到,而不是将回调传递给函数。除非您将它们全部返回,否则回调无法链接或捕获所有错误。

此外,在您有另一个承诺的那一刻,从所有.then 中返回。这会使事情变平。

【讨论】:

【参考方案2】:

Promise 迭代在我第一次尝试时也完全扭曲了我的大脑。我认为 Bluebird 的文档在区分常见用例方面做得相当差,但我不会继续讨论它,因为 (a) 我喜欢 Bluebird,并且 (b) 我没有时间更新文档。

我觉得Promise.map 适合您的场景。

myService.getSomeData(url)
    .then((data) => 
    
        return myOtherService.getMoreData(data.uniqueId)
    )
    .map((item) =>
    
        return doSomethingWithData(item);
    )
    .then((results) =>
    
        // do something with the result array. 
    );

根据您想要对结果执行的操作,我使用了.map,您也可以使用.reduce.each。请注意,.each 不会修改它所链接到的承诺的返回值,因此 Bluebird 文档中的“仅用于副作用”注释。

实例方法和静态方法之间的区别当然是静态方法必须提供数组,例如Promise.map(array, (item) => ).

另外,正如@jib 所说 - 始终在回调中返回一个值。这将为您节省很多痛苦。

【讨论】:

感谢您的示例。似乎doSomethingWithData() 需要在示例中返回一个promise——如果它不返回怎么办,例如只返回数字2?我应该在Promise.promisify 或类似的东西中包装对它的调用吗? @jkj2000 如果doSomethingWithData(item) 是异步的,你会想要返回一个承诺。如果签名真的是doSomethingWithData(item, callback),那么Promise.promisify 是个好主意,或者如果它已经实现,那么从一开始就考虑基于promise 的实现。一般来说,不,您不必返回承诺,任何值都可以,甚至是承诺和非承诺值的混合。

以上是关于从父承诺中解决一系列承诺的主要内容,如果未能解决你的问题,请参考以下文章

在不解决承诺的情况下使用 $http.post 和 res.redirect

在 Ember 车把模板中呈现已解决的承诺值

拒绝承诺时如何解决 UnhandledPromiseRejectionWarning

在更新状态和重定向之前等待所有承诺解决

Axios 承诺解决/待处理承诺

当其中一些得到解决时,解决合并后的承诺