【问题标题】:How to make a NodeJs function wait?如何让 NodeJs 函数等待?
【发布时间】:2016-10-29 23:59:05
【问题描述】:
例如我有这两个函数:
var count= function(){
for(i=1;i<=3;i++){
console.log(i);
}
setTimeout(function(){
for(i=1;i<=3;i++){
console.log(-i);
}
},2000);
}
var letters = function(){
var charSet = 'abcdefghijklmnopqrstuvvwxyz'
for(i=0;i<3;i++){
console.log(charSet[i]);
}
}
当我按此顺序执行它们时:
count();
letters();
我希望得到输出:
1 2 3 -1 -2 -3 a b c
但我得到的是:
1 2 3 a b c -1 -2 -3
为什么函数不等待超时完成?我怎样才能实现所需的行为?
【问题讨论】:
标签:
javascript
node.js
timeout
wait
【解决方案1】:
您没有收到1 2 3 -1 -2 -3 a b c 的原因是您的代码不会在setTimeout(...) 调用处停止。这是因为许多 JavaScript 方法本质上都是asynchronous。这意味着它们不会阻止您的代码流。这意味着当您调用setTimeout(...) 时,JavaScript 解释器将确保传递给setTimeout 的函数在2000ms 内运行,但不会停止并等待它。它将继续其正常的执行流程,进入下一条指令。
如果您希望它等待,您可以在打印出剩余的数字 (-1, -2, -3) 后调用 letters()。
setTimeout(function(){
for(i=1;i<=3;i++){
console.log(-i);
}
letters();
},2000);
【解决方案2】:
为什么函数不等待超时完成?
因为setTimeout 不是这样工作的。
实际发生的情况是您请求让您的函数在不少于 X 毫秒(在您的情况下为 2000 毫秒)内运行。 JS 运行时将等待所有其他代码完成运行,然后查看它是否至少有 X 毫秒。完成后,您的函数将运行。但与此同时,您可以运行任何其他 JS 代码。它故意不阻止其他代码运行。
我怎样才能实现所需的行为?
最好的答案是以不同的方式构建您的代码。您需要学习使用异步事件。最简单的方法是使用回调函数:
var count = function(cb) {
for (i = 1; i <= 3; i++) {
console.log(i);
}
setTimeout(function() {
for (i = 1; i <= 3; i++) {
console.log(-i);
}
// Run the function we passed to it after the rest is done
cb();
}, 2000);
}
var letters = function() {
var charSet = 'abcdefghijklmnopqrstuvvwxyz'
for (i = 0; i < 3; i++) {
console.log(charSet[i]);
}
}
count(letters); // Pass `letters` as a callback so it will be called after `count` is done
【解决方案3】:
因为setTimeout 安排第二个循环稍后运行(大约 2 秒),然后立即返回。
Node.js 用于异步、事件驱动的编程。您根本不想阻止执行 - 您要求的行为根本不是“想要的”。
我建议您阅读有关 Node.js 和异步编程的内容,然后重新审视您实际尝试做的事情。你可能想要更多这样的东西:
function count(callback) {
for (i=1; i<=3; i++){
console.log(i);
}
setTimeout(function() {
for(i=1;i<=3;i++){
console.log(-i);
}
callback();
}, 2000);
}
function letters() {
var charSet = 'abcdefghijklmnopqrstuvvwxyz'
for (i=0; i<3; i++){
console.log(charSet[i]);
}
}
然后像这样运行它:
count(letters);