Node.js的
while(list != []) {
apiCall.then(function(data){
list = data;
});
}
其中apiCall是一个承诺,如:
return new Promise(function (fulfill, reject){
request("url", function (error, response, body){
try {
fulfill(body);
} catch (error) {
reject(error);
}
}, reject);
});
因为api调用是异步的,所以出错了,循环永远不会结束。我该如何解决这个问题?
答案 0 :(得分:1)
您可以使用SynJS同步在循环内运行带回调的函数。这是一个工作代码来说明:
var SynJS = require('synjs');
var request = require('request');
function myFunction1(modules) {
var list, i=0;
while(i<5) {
modules.request("http://www.google.com", function (error, response, body){
list = body;
console.log("got it!", i, new Date());
modules.SynJS.resume(_synjsContext); //<-- indicates that callback is finished
});
SynJS.wait(); //<-- wait for callback to finish
i++;
};
};
var modules = {
SynJS: SynJS,
request: request,
};
SynJS.run(myFunction1,null,modules,function (ret) {
console.log('done');
});
结果如下:
got it! 0 Thu Jan 05 2017 18:17:20 GMT-0700 (Mountain Standard Time)
got it! 1 Thu Jan 05 2017 18:17:20 GMT-0700 (Mountain Standard Time)
got it! 2 Thu Jan 05 2017 18:17:21 GMT-0700 (Mountain Standard Time)
got it! 3 Thu Jan 05 2017 18:17:21 GMT-0700 (Mountain Standard Time)
got it! 4 Thu Jan 05 2017 18:17:21 GMT-0700 (Mountain Standard Time)
done
答案 1 :(得分:0)
您不能使用等待异步结果的同步while
循环。异步回调,在这种情况下,.then()
处理程序永远不会执行。你只是无法用这种方式编写单线程Javascript。解释器只是永远地继续运行你的while循环,虽然事件可能堆积在事件队列中以触发异步回调,但这些事件永远不会得到服务,因为你的while
循环永远不会停止。你无法以这种方式在事件驱动的单线程环境中编写异步行为,例如Javascript。
相反,您不需要使用同步循环。典型的解决方案包括进行异步调用,评估结果。如果要在此时再次执行异步函数,则进行函数调用以再次执行它。
function runIt() {
return a().then(function() {
if (needToRunAgain) {
return runIt();
} else {
return someValue;
}
});
}
如果条件需要,它将再次调用异步操作,并将生成的promise链接到原始promise,允许调用者确切地知道结果何时完成。然后,您可以调用以下代码:
runIt(...).then(function(result) {
// result here
// you must use the async result here or call a function and pass the result
// to it. You cannot assign it to a higher scoped variable and expect
// other code that follows to be able to use it.
}, function(err) {
error here
});