承诺瀑布

Chr*_*ich 5 javascript asynchronous node.js 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
})
Run Code Online (Sandbox Code Playgroud)

很明显,使用回调并没有多少收获.而不是"回调地狱"我现在得到了"承诺地狱".

我看过npm bluebird,但似乎并不支持瀑布承诺.

有时我会使用async和wrap返回promise的任务:

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
});
Run Code Online (Sandbox Code Playgroud)

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

什么是更好的方法?

piz*_*r0b 14

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

promiseOne()
    .then(() => promiseTwo())
    .then(() => promiseThree())
    .then(() => promiseFour());
Run Code Online (Sandbox Code Playgroud)

顺便说一句,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(() => { ... });
Run Code Online (Sandbox Code Playgroud)

  • 感谢您的澄清,但您的解决方案无法满足将一个异步调用的结果传递到另一个异步调用. (2认同)
  • @ChrisRich (2认同)