Tri*_*daz 10 javascript asynchronous synchronous node.js
我有一个不是 Web应用程序的节点应用程序 - 它在返回之前完成一系列异步任务1.在返回之前,程序的结果立即打印到控制台.
如何在返回之前确保完成所有异步工作?通过确保我们在调用res.end()之前完成的所有任务,我能够在Web应用程序中实现类似的功能,但在让脚本返回之前,我没有任何等效的最终"事件".
请参阅下面的我当前的(损坏的)功能,试图等到callStack为空.我刚刚发现这是一种无意义的方法,因为node在进入processObjWithRef中调用的任何异步函数之前等待processHub完成.
function processHub(hubFileContents){
var callStack = [];
var myNewObj = {};
processObjWithRef(samplePayload, myNewObj, callStack);
while(callStack.length>0){
//do nothing
}
return 1
}
Run Code Online (Sandbox Code Playgroud)
注意:我曾多次尝试使用async之类的库来实现这种行为(请参阅我的相关问题如何在nodejs中同步调用此请求?)所以请在建议之前考虑答案和注释答案基于'只是使用asynch'.
你不能在返回之前等待异步事件 - 这是异步的定义!试图强制Node进入这种编程风格只会让你感到痛苦.一个简单的例子是定期检查是否callstack为空.
var callstack = [...];
function processHub(contents) {
doSomethingAsync(..., callstack);
}
// check every second to see if callstack is empty
var interval = setInterval(function() {
if (callstack.length == 0) {
clearInterval(interval);
doSomething()
}
}, 1000);
Run Code Online (Sandbox Code Playgroud)
相反,在Node中执行异步内容的常用方法是实现对函数的回调.
function processHub(hubFileContents, callback){
var callStack = [];
var myNewObj = {};
processObjWithRef(samplePayload, myNewObj, callStack, function() {
if (callStack.length == 0) {
callback(some_results);
}
});
}
Run Code Online (Sandbox Code Playgroud)
如果你真的想要归还某些东西,请查看承诺 ; 他们保证在解决时立即或在将来的某个时间点发出事件.
function processHub(hubFileContents){
var callStack = [];
var myNewObj = {};
var promise = new Promise();
// assuming processObjWithRef takes a callback
processObjWithRef(samplePayload, myNewObj, callStack, function() {
if (callStack.length == 0) {
promise.resolve(some_results);
}
});
return promise;
}
processHubPromise = processHub(...);
processHubPromise.then(function(result) {
// do something with 'result' when complete
});
Run Code Online (Sandbox Code Playgroud)
问题出在你的功能设计上。您想要从异步执行的任务列表中返回同步结果。
您应该使用一个额外的参数来实现您的函数,该参数将是回调,您将在其中放置结果(在本例中为 1),以便某些消费者对其执行某些操作。
另外,您的内部函数中还需要有一个回调参数,否则您将不知道它何时结束。如果最后一件事不可能,那么您应该进行某种轮询(也许使用 setInterval)来测试 callStack 数组何时填充。
请记住,在 Javascript 中,您永远不应该进行忙碌等待。这将完全锁定您的程序,因为它在单个进程上运行。