0

我正在构建一个 NodeJS 应用程序(使用 Sails,但我想这无关紧要)。

在我的行动中,我有许多需要加载的对其他服务、数据源等的请求。但是,由于对回调的巨大依赖,我的代码在操作返回 HTML 后很长时间仍在执行。

我一定是错过了一些愚蠢的事情(或者没有完全了解整个异步的事情),但是在我准备好所有数据来渲染视图之前,我到底要如何阻止我的动作完成呢?!

干杯

4

5 回答 5

2

我建议与异步库非常亲密

上面的链接的文档非常好,但它基本上归结为一堆非常方便的调用,例如:

async.parallel([
    function(){ ... },
    function(){ ... }
], callback);

async.series([
    function(){ ... },
    function(){ ... }
]);

Node本质上是异步的,你需要学会爱上它。

于 2014-02-17T16:23:05.937 回答
1

很难确切地说出问题出在哪里,但这里有一个猜测。假设您只有一个外部调用,您的代码应如下所示:

exports.myController = function(req, res) {

    longExternalCallOne(someparams, function(result) {

       // you must render your view inside the callback
       res.render('someview', {data: result});
    });

    // do not render here as you don't have the result yet. 

}

如果您有两个以上的外部调用,您的代码将如下所示:

exports.myController = function(req, res) {

    longExternalCallOne(someparams, function(result1) {

       longExternalCallTwo(someparams, function(result2) {

         // you must render your view inside the most inner callback
         data = {some combination of result1 and result2};
         res.render('someview', {data: data });

       });

       // do not render here since you don't have result2 yet

    });

    // do not render here either as you don't have neither result1 nor result2 yet. 

}

如您所见,一旦您有多个长时间运行的异步调用,事情就会开始变得棘手。上面的代码仅用于说明目的。如果您的第二个回调取决于第一个回调,那么您需要类似的东西,但如果 longExternalCallOne 和 longExternalTwo 彼此独立,您应该使用像async这样的库来帮助并行化请求https://github.com/caolan/async

于 2014-02-17T16:30:59.193 回答
0

你不能停止你的代码。如果一切都已完成,您所能做的就是检查所有回调。如果是,请继续使用您的代码。如果否,请等待下一次回调并再次检查。

于 2014-02-17T16:18:55.663 回答
0

我在这里猜测,因为没有代码示例,但你可能会遇到这样的事情:

// let's say you have a function, you pass it an argument and callback
function myFunction(arg, callback) {
    // now you do something asynchronous with the argument
    doSomethingAsyncWithArg(arg, function() {
        // now you've got your arg formatted or whatever, render result
        res.render('someView', {arg: arg});
        // now do the callback
        callback();
        // but you also have stuff here!
        doSomethingElse();

    });
});

所以,在你渲染之后,你的代码会继续运行。如何预防?return从那里。

return callback();

现在您的内部函数将在调用回调后停止处理。

于 2014-02-18T01:01:21.327 回答
0

你不应该停止你的代码,而是在你的其他资源回调中渲染你的视图,所以你在渲染之前等待你的资源被访问。这是 node.js 中的常见模式。

如果您必须等待多个回调被调用,您可以在每次调用一个回调时手动检查是否也调用了其他回调(例如使用简单的 bool),如果是,则调用您的渲染函数。或者您可以使用异步或其他很酷的库,这将使任务更容易。Promises(使用 bluebird 库)也可以是一个选项。

于 2014-02-17T16:24:24.337 回答