javascript - 我应该如何构造 promise 来处理多个依赖的异步任务?

标签 javascript asynchronous promise

我读了一些如何重构代码以适应 promise 风格的示例,但似乎 they可能需要其他 Promise 库的帮助。

我的问题是我有多个异步任务,其中一些任务可能依赖于另一个调用的某些信息。 所以我的代码看起来像这样:

假设我有一个图书馆表。图书馆表有很多书。一本书有很多页。一个页面有很多照片。

我还使用 LoopBack 为这些表创建实例。

我有一个这种格式的库对象数组。

{
    "location": "Hong Kong Island",
    "size": "25sq meter",
    "availableBooks" : [
        {
            "bookName": "Harry Potter",
            "pages": 235,
            "author": "J R Rowling"
            "pages": [
                {
                    "page": 1,
                    "content": "XXX",
                    "photos": [
                        {
                            "urlLink": "https://someLink",
                            "size": "360X250"
                        },
                        {
                            "urlLink": "https://google",
                            "size": "650X250"
                        }

                    ]
                }
                ,
                {
                    "page": 2,
                    "content": "XXX"
                }
            ]
        },
        {
            "bookName": "Lord Of The Rings",
            "pages": 335,
            "author": "J. R. R. Tolkien"

        }

    ]
} 

对于伪代码,它看起来像这样。

for(something){
    asyncCallA()
    .then((A) => {
        for(something){
            asyncCallB(A)
                .then((B) => {
                    for(something){
                        asyncCallC(B)
                        .then((C) => {
                            for(something){
                                asyncCallD(C)
                            }
                        })
                    }

                })
        }
    })

}

对于常见情况,我了解如何使用 Promise 来链接异步操作。但在这种情况下,异步调用相互依赖并涉及大量 for 循环,我不知道如何扁平化调用。有人可以提供一些见解吗?谢谢。

最佳答案

尚不清楚您到底在问什么,但在 for 循环内,您可以用链接替换嵌套。所以像这样:

       asyncCallB(A)
        .then((B) => {
            asyncCallC(B)
            .then((C) => {
                asyncCallD(C)
            })
        })

可以替换为:

       asyncCallB(A).then(B => {
         return asyncCallC(B);
       }).then(C => {
         return asyncCallD(C);
       });

如果您希望一个 for 循环迭代等待前一个循环迭代完成(尽管您没有显示从一个循环迭代到下一个循环迭代需要的任何依赖关系),那么您必须要么将 await 与主循环 Promise 一起使用(并且父函数必须声明为 async),或者必须切换到除 之外的手动迭代方式>for 循环。

    for(...) {
       let loopResult = await asyncCallB(A).then(B => {
         return asyncCallC(B);
       }).then(C => {
         return asyncCallD(C);
       });
    }

或者,很多时候,循环的各种迭代可以并行进行,但您想知道它们何时全部完成:

    let promises = [];
    for(...) {
       let p = asyncCallB(A).then(B => {
         return asyncCallC(B);
       }).then(C => {
         return asyncCallD(C);
       });
       promises.push(p)
    }
    Promise.all(promises).then(results => {
       // all promises in the loop done now
    });

我还找到了Bluebird promise library对于迭代非常有用,因为它具有 Promise.map()Promise.each()Promise.reduce() 等内容>Promise.mapSeries() 为您提供对迭代的一些控制(包括它是并行还是串行以及您想要允许多少并发)并为您完成更多工作。

相关答案:

Using Promises with fs.readFile in a loop

Proper while() loop for bluebird promises (without recursion?)

How to synchronize a sequence of promises?

Javascript while loop where condition is a promise

bluebirdjs promises wrapped inside a for loop

How to chain promises in for loop in vanilla javascript

How to chain an async ajax function in a loop

JavaScript: Perform a chain of promises synchronously

关于javascript - 我应该如何构造 promise 来处理多个依赖的异步任务?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47123143/

相关文章:

javascript - 找出文档准备就绪时的初始宽度(不是当前宽度)

asynchronous - 获取方法 Future<T> 的结果 flutter

javascript - jQuery - 异步 Ajax 请求?

javascript - 为什么用 p.then(resolve) 比用 resolve(p) 更早地解决新的 promise ?

node.js - NodeJS 服务函数未定义

javascript - 在生成器函数之后继续的正确方法

javascript - 为什么这个 For 循环会使浏览器实验室崩溃?

javascript - 如何改变小图片相对于大图片的位置?

javascript Boolean() 函数无法正常工作

c# - 什么时候使用 await async 不好?