【问题标题】:Javascript techniques to embed nested callback functions嵌入嵌套回调函数的 Javascript 技术
【发布时间】:2014-10-14 19:52:47
【问题描述】:

我正在使用 Nodejs 构建一个应用程序。我对前端 javascript 相当流利,其中异步事件很少变得太复杂,也不会那么深入。但是现在我使用的是全事件驱动的 Node,对相互依赖的不同服务器和数据库进行大量调用变得相当集群化。

将 next() 函数作为参数传递似乎很常见,一旦第一个事件完成,就会调用该函数。这很好用,但是当需要在下一个函数之后具有下一个函数时,我正在努力保持可读代码。

让我通过例子来解释。

假设我有一个这样定义的路线:

app.use('/fetchData', function(req, res) {

});

所以在我们返回数据之前,我需要进行一些异步调用。

  • 首先到数据库中检索登录详细信息。

  • 然后使用登录详细信息,我需要再次调用外部服务器以登录并检索原始信息。

  • 然后第三个我需要回到数据库做一些检查。

    然后最后将数据返回给用户。

你会怎么做?我正在尝试这样,但无法正确使用,也无法阅读:

app.use('/fetchData', function(req, res) {
    
    //First I create a user object to pass information around to each function
    var user = {...};

    var third = database.doSomeChecks;

    var second = server.externalCall(user, third);

    //first
    database.getLoginDetails(user, second);
});

显然 second 实际运行函数并将 second 设置为返回值。但我似乎可以将正确的信息传递给第二个。

我认为一个选项可能是通过一组回调并始终调用数组中的最后一个函数并将其删除。

app.use('/fetchData', function(req, res) {
    
    //First I create a user object to pass information around to each function including the req and res object to finally return information
    var user = {...};

    var third = database.doSomeChecks;

    var second = server.externalCall;

    //first
    database.getLoginDetails(user, [third, second]);
});

你的技术是什么?上面提到的数组思路是不是最好的解决方案?

【问题讨论】:

  • 使用承诺...
  • Promises 或者你可以查看async 包。
  • 一路承诺。看看 q.js。
  • 你想要function second(err, loginResults) { server.externalCall(user, third); } - 一直嵌套回调。或者使用 Promise 进行一次回调并返回一个结果(例如,不是 app.use

标签: javascript node.js asynchronous


【解决方案1】:

我建议您根据个人喜好使用 Promise 我喜欢使用 bluebird 它易于实现,性能非常好,并且还有一些很酷的功能可供使用。

有了 Promise,更容易阅读控制流执行(至少对我而言),很多人抱怨回调地狱,并承诺它是可能的解决方案之一。

你可以这样做:

来自:

var user = {...};

var third = database.doSomeChecks;

var second = server.externalCall(user, third);

收件人:

var user = {...};
checkDB(query).then(
function(data){
    //data checks
    return value 
}).then(
    function(value){
        // value returned from the previous promise
        return server.externalCall(value);
    });

你可以看看这个答案,看看你如何处理nested比回调容易得多的承诺。

希望对你有帮助。

【讨论】: