首页 > 解决方案 > 使用 Promise 链接多个异步函数

问题描述

在这段代码中:

new Promise((resolve, reject) => {
    DB.get(params, function(err, data) {
        if (err) reject(err)
        else resolve(data.Item)
    })
})
.then((data) => {
    let params = { Name: 'DEMO' }
    CWevents.putRule(params, function(err, data) {
        if (err) console.log("Error", err)
        else console.log("Success")
    })
})
.then(() => {
    let params = { Rule: 'DEMO' }
    CWevents.putTargets(params, function(err, data) {
        if (err) console.log("Error", err)
        else console.log("Success", data)
    })
})

这里的DB.get函数有一个回调,但是将多个回调放在一起看起来很糟糕,所以我决定使用 Promise。我创建了一个新的 Promise,里面是一个异步函数。在它完成运行后,它会根据需要解决并且第一个.then开始工作。然后在第一个内部.then我有另一个异步函数,它的工作原理与第一个非常相似。

resolve/reject但这次没有跑了。所以第三个.then在第二个内部的函数.then完成之前运行。如何让第三个.then等到第二个完成运行?那么函数1完成运行,然后函数2,然后3?

标签: javascriptnode.jsasynchronouspromise

解决方案


您可以将调用包装在CWEvents.putRulePromise 中。然后你可以从CWEvents.putRule. 这可以通过一个thenerror

您的代码应如下所示

new Promise((resolve, reject) => {
    DB.get(params, function(err, data) {
        if (err) reject(err);
        else resolve(data.Item);
    });
})
    .then(data => { // data not needed as you are not using it in the remaining code
        let params = { Name: "DEMO" };
        return new Promise((resolve, reject) => {
            CWevents.putRule(params, function(err, data) {
                if (err) {
                    console.log("Error", err);
                    reject(err)
                } else {
                    console.log("Success");
                    resolve() // resolve(data) if you want to pass the data from CWEvents.putRule
                }
            });
        });
    })
    .then(() => {
        let params = { Rule: "DEMO" };
        CWevents.putTargets(params, function(err, data) {
            if (err) console.log("Error", err);
            else console.log("Success", data);
        });
    });

您可以使用更具可读性的方式做同样的事情async await

async function process() {
    try {
        var data = new Promise((resolve, reject) => {
            DB.get("params", function(err, data) {
                if (err) reject(err);
                else resolve(data.Item);
            });
        }); // this will return a promise to the variable data

        var response = (function processData(data) {
            let params = { Name: "DEMO" };
            return new Promise((resolve, reject) => {
                CWevents.putRule(params, function(err, data) {
                    if (err) {
                        console.log("Error", err);
                        reject(err);
                    } else {
                        console.log("Success " + data.Item);
                        resolve(data);
                    }
                });
            });
        })(await data);
        /* by using the await keyword , we can wait for the promise to be complete before moving on to the next step
          of execution.
        */

        /*
         * waiting on the response promise to complete
         */
        if (await response) {
            let params = { Rule: "DEMO" };
            CWevents.putTargets(params, function(err, data) {
                if (err) console.log("Error", err);
                else console.log("Success", data);
            });
        }
    } catch (e) {
        console.log("Error occured during operation " + e);
    }
}

process();

您可以在 MDN 上找到更多详细信息async await


推荐阅读