Nodejs for循环问题
Nodejs for循环问题
for (var i = 0; i < 2; i++) {
console.log(“循环:”,i)
result_1[i] = []
use(_match[i],"match",_lotterytype[i], function(result)
{
// console.log("循环:",i)
console.log("match:",i)
// console.log(result);
result_1[i].push(result)
use(_sort[i],"sort",_lotterytype[i], function(result)
{
console.log("sort:",i)
// console.log(result);
result_1[i].push(result)
use(_option[i],"option",_lotterytype[i], function(result)
{
console.log("option:",i)
// console.log(result);
result_1[i].push(result)
// ser.emit("done",result_1)
})//option
})//sort
})//match
};
use是一个函数,函数内部会读取文件。
让我不能理解的是,输出结果会是
循环: 0 循环: 1 match: 2
按说在每次循环的时候都应该输出 一次 console.log(“match:”,i) console.log(“sort:”,i) console.log(“option:”,i) 才对啊 为什么看起来就好像for循环跑过头了似的?
小弟对于nodejs的for循环异步还是有些不甚理解,还望各位指点一二。
您提到的问题是因为 for
循环中的异步操作导致的。在您的代码中,use
函数是异步的,这意味着当循环执行到 use
函数时,它不会立即阻塞等待 use
完成,而是继续执行下一个循环迭代。这会导致在所有异步操作完成之前,循环已经结束。
让我们详细分析一下代码,并提供一个改进后的版本来解决这个问题。
原始代码的问题
for (var i = 0; i < 2; i++) {
console.log("循环:", i);
result_1[i] = [];
use(_match[i], "match", _lotterytype[i], function(result) {
console.log("match:", i);
result_1[i].push(result);
use(_sort[i], "sort", _lotterytype[i], function(result) {
console.log("sort:", i);
result_1[i].push(result);
use(_option[i], "option", _lotterytype[i], function(result) {
console.log("option:", i);
result_1[i].push(result);
// ser.emit("done", result_1);
}); // option
}); // sort
}); // match
}
解决方案
您可以使用 async/await
和 Promise
来处理这些异步操作,以确保每个循环迭代中的异步操作按顺序完成。
改进后的代码
const asyncFunctionRunner = async () => {
let result_1 = [];
for (let i = 0; i < 2; i++) {
console.log("循环:", i);
result_1[i] = [];
await new Promise((resolve, reject) => {
use(_match[i], "match", _lotterytype[i], async (result) => {
console.log("match:", i);
result_1[i].push(result);
await new Promise((resolve, reject) => {
use(_sort[i], "sort", _lotterytype[i], async (result) => {
console.log("sort:", i);
result_1[i].push(result);
await new Promise((resolve, reject) => {
use(_option[i], "option", _lotterytype[i], async (result) => {
console.log("option:", i);
result_1[i].push(result);
resolve();
}); // option
}); // sort
}); // sort
}); // match
}); // match
}); // promise wrapper
}
// ser.emit("done", result_1);
};
asyncFunctionRunner();
解释
- 异步函数:我们定义了一个名为
asyncFunctionRunner
的异步函数。 - 循环:在循环中,我们使用
await
关键字来等待每个异步操作完成。 - Promise 包装器:为了使
use
函数的回调能够与await
一起使用,我们将每个use
调用包装在一个新的Promise
中。 - 按顺序执行:通过这种方式,我们可以确保每个异步操作在继续下一个操作之前都已完成。
这样,您就可以确保每个 use
调用都在前一个调用完成后执行,从而避免了异步操作导致的混乱输出。
在Node.js中,由于JavaScript的事件循环机制,for
循环中的异步操作(如回调函数)可能会导致你看到不符合预期的结果。具体来说,在你的例子中,use
函数是异步的,这意味着for
循环会立即执行完所有迭代,并且在这些迭代结束之前不会等待异步操作完成。
为了更好地理解这一点,可以考虑以下几点:
for
循环会立即执行完所有迭代。- 每次调用
use
时,都会将一个异步操作添加到事件队列中。 - 由于异步操作不是立即完成的,
for
循环可能在所有异步操作完成之前就结束了。
这会导致你在循环结束后才看到异步操作的结果。你可以通过使用闭包或者使用async/await
来解决这个问题。以下是使用闭包和async/await
的示例:
使用闭包
for (let i = 0; i < 2; i++) {
(function(i) {
console.log("循环:", i);
result_1[i] = [];
use(_match[i], "match", _lotterytype[i], function(result) {
console.log("match:", i);
result_1[i].push(result);
use(_sort[i], "sort", _lotterytype[i], function(result) {
console.log("sort:", i);
result_1[i].push(result);
use(_option[i], "option", _lotterytype[i], function(result) {
console.log("option:", i);
result_1[i].push(result);
// ser.emit("done", result_1);
});
});
});
})(i);
}
使用 async/await
async function process() {
for (let i = 0; i < 2; i++) {
console.log("循环:", i);
result_1[i] = [];
await new Promise((resolve) => {
use(_match[i], "match", _lotterytype[i], function(result) {
console.log("match:", i);
result_1[i].push(result);
use(_sort[i], "sort", _lotterytype[i], function(result) {
console.log("sort:", i);
result_1[i].push(result);
use(_option[i], "option", _lotterytype[i], function(result) {
console.log("option:", i);
result_1[i].push(result);
resolve();
});
});
});
});
}
}
process();
在这个示例中,我们使用了async/await
来确保每个异步操作完成后才会继续下一个迭代。这样可以确保每个异步操作的结果按顺序输出。