【问题标题】:Promise waterfall [duplicate]承诺瀑布[重复]
【发布时间】:2017-05-05 00:50:21
【问题描述】:

我是一名 API 开发人员,通常编写需要将一个异步调用的结果传递给另一个异步调用(即异步瀑布)的端点。

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

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,那将不会起作用,因为一个任务的结果不会传递给下一个任务。

有什么更好的方法?

【问题讨论】:

  • 除了 realseanp 的回答(你使用错误的承诺)你应该知道有一个承诺的 async.js 库 - async-q (npmjs.com/package/async-q) 直接与承诺一起工作,所以你可以在没有所有回调包装的情况下返回承诺。

标签: javascript node.js asynchronous bluebird


【解决方案1】:

你有一个承诺反模式正在发生。您可以从 Promise 返回 Promise 以避免像您所做的那样嵌套 Promise。

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(() => { ... });

【讨论】:

  • 感谢您的澄清,但您的解决方案不适合将结果从一个异步调用传递到另一个。
  • 仅供参考,你可以说promiseOne().then(() => promiseTwo()).then(() => promiseThree()).then(...etc)
  • Doh... 你是绝对正确的:我做错了承诺。得到它的工作:-)
  • @ChrisRich ? ???
猜你喜欢
  • 1970-01-01
  • 2017-03-27
  • 2017-09-10
  • 2016-09-29
  • 1970-01-01
  • 2015-07-10
  • 2017-02-17
  • 2015-08-06
相关资源
最近更新 更多