从父Promise中解决一系列Promise

IT技术 javascript promise bluebird
2021-02-04 13:08:30

这是我对嵌套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 元素长度的数组中。这是我开始迷失的地方,因为我不确定如何制作这种方法以及我应该从中返回什么。我在蓝鸟的采取了一些刺Promise.allPromise.map,但我挣扎,我想我会征求意见。

2个回答

回报所有的Promise!

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

此外,.then当你有另一个Promise时,从所有的's返回这会使事情变得扁平。

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它不会修改链接到的Promise的返回值,因此 Bluebird 文档中的“仅用于副作用”注释。

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

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

@jkj2000 如果doSomethingWithData(item)是异步的,你会想要返回一个Promise。如果签名是真的doSomethingWithData(item, callback),然后Promise.promisify是一个好主意,或者如果它尚未实现然后才考虑从一开始就基于Promise的实现。一般来说,不,您不必返回Promise,任何值都可以,即使是Promise值和非Promise值的混合。
2021-03-29 13:08:30
谢谢你的例子。似乎doSomethingWithData()需要在示例中返回一个Promise——如果它没有,例如只返回数字 2 怎么办?我应该把对它的调用包装起来Promise.promisify还是沿着这些路线?
2021-03-31 13:08:30