我有一个正在构建的NodeJS应用程序(使用Sails,但我认为这无关紧要)。
在我的行动中,我对我需要加载的其他服务,数据源等有很多要求。但是,由于对回调的巨大依赖性,我的代码在操作返回HTML后仍然执行很久。
我一定是在遗漏一些愚蠢的东西(或者说并没有完全得到整个异步的东西)但是我到底该如何阻止我的行动结束,直到我准备好所有数据来呈现视图?!
干杯
答案 0 :(得分:2)
我建议与async library
非常亲密上面的链接文档非常好,但它基本上归结为一堆非常方便的调用:
async.parallel([
function(){ ... },
function(){ ... }
], callback);
async.series([
function(){ ... },
function(){ ... }
]);
节点固有的异步,你需要学会喜欢它。
答案 1 :(得分: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 这样的库来帮助并行化请求{{3} }
答案 2 :(得分:0)
您无法停止代码。如果一切都完成,您只需检入所有回调。如果是,请继续使用您的代码。如果不是,请等待下一次回调并再次检查。
答案 3 :(得分:0)
您不应该停止代码,而是在其他资源回调中呈现您的视图,以便在呈现之前等待您的资源到达。这是node.js中的常见模式。
如果你必须等待几个回调被调用,你可以每次调用一个回调,如果其他人也被调用(例如,使用简单的bool),如果是,则调用你的渲染函数。或者您可以使用异步或其他酷库,这将使任务更容易。 Promises(使用bluebird库)也是一种选择。
答案 4 :(得分: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();
现在你的内部函数在调用回调函数后会停止处理。