Javascript - 按顺序调用两个异步函数

时间:2017-01-17 11:24:18

标签: javascript asynchronous promise

我有一个看起来像这样的代码

class foo {
    constructor() {

        // calling a, b, c synchronously
        a().then(
            function(response) {
                b().then(
                    function(response) {
                        c();
                    }, function(error) {
                        // pass
                    }
                );
            }, function(error) {
                // pass
            }
        );
    }

    a() {
        return new Promise(function(fullfill, reject) {

            // x is any function that returns a promise, making the
            // implementation of this function "a" asynchronous
            x().then(
                function(response) {
                    fullfill(response);
                }, function(error) {
                    reject(error);
                }
            );

        });
    }

    b() {
        return new Promise(function(fullfill, reject) {

            // x is any function that returns a promise, making the
            // implementation of this function "b" asynchronous
            x().then(
                function(response) {
                    fullfill(response);
                }, function(error) {
                    reject(error);
                }
            );

        });
    }

    c() {
        // do something
    }

}

基本上,我有两个函数ab,它们都是异步的。 这些函数是异步的,因为它们都调用一些返回promise的函数x(在我的例子中,它是对数据库的查询)。

我需要拨打a,然后是b,然后是c,但是按顺序。这样做的一种方法是我在上面的代码中实现的,但它导致了令人讨厌的嵌套承诺响应。

有没有其他方法可以实现相同的结果,而不使用以下语法(因为如果这是唯一可能的解决方案,那么我可能根本不使用它。)

2 个答案:

答案 0 :(得分:1)

使用promise链接,如下所示:

a().then(resA => {
    // resA is response of function a()
    // Do whatever you want with resA here
    // and then return promise of function b()

    return b();
})
.then(resB => {
    // resB is response of function b()
    // Do whatever you want with resA here
    // and then return promise of function c()

    return c();
})
.then(resC => {
    // resC is response of function c()
    // Do whatever you want with resC here
})
.catch(err => {
    // Handle any reject/error of functions a, b or c
});

如果你想将函数a和b的响应带到最后,你可以按如下方式进行链接:

a().then(resA => {
    // resA is response of function a()
    // Do whatever you want with resA here
    // and then return promise of function b()

    return b().then(resB => { resA: resA, resB: resB });
})
.then(res => {
    // res is a object with rsponse of function a() & b()
    // res.resA is response of function a()
    // res.resB is response of function b()
    // Do whatever you want to with the responses here
    // then return promise of function c()

    return c().then(resC, { resA: res.resA, resB: res.resB, resC: resC });
})
.then(resC => {
    // res is a object with rsponse of function a(), b() & c()
    // res.resA is response of function a()
    // res.resB is response of function b()
    // res.resC is response of function c()
    // Do whatever you want to with the responses
})
.catch(err => {
    // Handle any reject/error of functions a, b or c
});

以上代码详细说明了演示/解释。它可以通过ES6减少,如下所示

a().then(resA => {
    // resA is response of function a()
    // Do whatever you want with resA here
    // and then return promise of function b()

    return b().then(resB => { resA, resB });
})
.then(res => {
    // res is a object with rsponse of function a() & b()
    // res.resA is response of function a()
    // res.resB is response of function b()
    // Do whatever you want to with the responses here
    // then return promise of function c()

    return c().then(resC, Object,assign(res, { resC }));
})
.then(resC => {
    // res is a object with rsponse of function a(), b() & c()
    // res.resA is response of function a()
    // res.resB is response of function b()
    // res.resC is response of function c()
    // Do whatever you want to with the responses
})
.catch(err => {
    // Handle any reject/error of functions a, b or c
});

希望这有帮助。

答案 1 :(得分:0)

设seq = [f1,f2,...,fn]是零参数保证的序列 返回功能。建立一个将执行它们的承诺p 在f {i-1}之后按顺序调用fi。

var p = seq.reduce(          (p_acc,f)=> p_acc.then(()=> f())         )

然后你可能想做

p.catch(...)