承诺瀑布

时间:2016-11-10 03:24:12

标签: javascript node.js asynchronous bluebird

我是一名API开发人员,通常会编写端点,要求将结果从一个异步调用传递到另一个异步调用,即async waterfall。

我通常使用promises以下方式执行此操作:

task1()

.then(result1){

    task2(result1)

    .then(result2){

        task3(result2)

        .then(result3){
            // API response
        })

        .catch(function(err){
            // Task 3 handle err
        })
    })

    .catch(function(err){
        // Task 2 handle err
    })
})

.catch(function(err){
    // Task 1 handle err
})

很明显,使用回调并没有多少收获。我没有“回调地狱”,而是“承诺地狱”。

我查看了npm bluebird,但似乎不支持瀑布承诺。

有时我会使用async并包装返回承诺的任务:

const tasks = [

    job1: function(cb){

        task1()

        .then(function(result){
            cb(null, result);
        })

        .catch(function(err){
            cb(err);
        })  
    },

    job2: function(cb, result1){

        task2(result1)

        .then(function(result){
            cb(null, result);
        })

        .catch(function(err){
            cb(err);
        })  
    },

    job3: function(cb, result2){

        task3(result2)

        .then(function(result){
            cb(null, result);
        })

        .catch(function(err){
            cb(err);
        })  
    }
]

async.series(tasks, function(err, results){

    if(err){
        // handle error
    }

    // API callback
});

但这也没用。 如果你正在考虑Promise.all不能工作,因为一个任务的结果不会传递给下一个任务。

什么是更好的方法?

1 个答案:

答案 0 :(得分:11)

你有一个承诺反模式发生。您可以从承诺中返回承诺,以避免像您一样嵌套承诺。

promiseOne()
    .then(() => promiseTwo())
    .then(() => promiseThree())
    .then(() => promiseFour());

顺便说一下,Node支持内置的Promise构造函数。

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise

const promise = new Promise((resolve, reject) => {
    // do something and then resolve
    resolve();
})
promise().then(() => { ... });