Nodejs 请问node中的for循环如何解决?

Nodejs 请问node中的for循环如何解决?

  for(var i=0; i<10; i++){

//console.log(i); 

var a = {seller_id : 1, order_id : 2};
console.log(i);
newAlready = new Already(a);
newAlready.save(function(err, doc){
  console.log(doc); 
});

}

我运行,但是只会插入执行一次newAlready.save,这是异步问题吗?谢谢!


16 回复

当然可以。你遇到的问题确实是由于JavaScript的异步特性导致的。在你的代码中,newAlready.save() 是一个异步操作,而 for 循环会立即执行完所有迭代,而不是等待每个异步操作完成。因此,当异步操作最终完成时,i 的值可能已经改变,导致所有操作使用相同的 i 值。

解决方案

为了解决这个问题,你可以使用几种不同的方法。以下是其中的一些解决方案:

1. 使用闭包

通过创建一个新的函数作用域来捕获每次循环中的 i 值,从而确保每个异步操作都能正确地访问到正确的 i 值。

for (var i = 0; i < 10; i++) {
    (function(index) {
        var a = { seller_id: 1, order_id: index + 2 };
        newAlready = new Already(a);
        newAlready.save(function (err, doc) {
            console.log(doc);
        });
    })(i);
}

2. 使用 let 替代 var

ES6 引入了 let 关键字,它可以创建块级作用域的变量。这使得每个循环迭代都有自己的 i 变量副本。

for (let i = 0; i < 10; i++) {
    var a = { seller_id: 1, order_id: i + 2 };
    newAlready = new Already(a);
    newAlready.save(function (err, doc) {
        console.log(doc);
    });
}

3. 使用 async/awaitPromise

如果你希望更清晰地处理异步流程,可以考虑使用 async/await 结合 Promise

(async () => {
    for (let i = 0; i < 10; i++) {
        var a = { seller_id: 1, order_id: i + 2 };
        let newAlready = new Already(a);
        await newAlready.save();
        console.log(newAlready);
    }
})();

总结

上述方法都可以解决你在循环中遇到的异步问题。选择哪种方法取决于你的具体需求和代码风格偏好。let 是最简单的方法,而 async/await 则提供了更清晰的异步流程控制。


是,这样肯定不行!

这种东西网上很多吧…用个闭包就可以搞定…

  for(var i=0; i<10; i++){
//console.log(i); 

(function (i) { var a = {seller_id : 1, order_id : 2}; console.log(i); var newAlready = new Already(a); newAlready.save(function(err, doc){ console.log(doc); }); })(i)

}

请问怎么解决?

试了下,不能解决,运行结果: 0 1 2 3 4 5 6 7 8 9 connected as id 156 9 [ { order_id: 2, seller_id: 1, _id: 53b24e9a48e957361684cfcb } ]

这里没有闭包,不需要,主要问题是mongoose,第一次成功了,后几次都失败了,doc是null所以显示不出来,你输出err试试

使用async库,如果想本次循环结束再进行下次循环就使用async.whilst方法,如果要并行,就是用集合操作async.forEach

不会只执行一次吧,看代码应该是会执行10次的。

楼主,不是你这么干的吧,用async

我也用async模块

使用async promise 等同步模块吧~

肯定是newAlready.save自身的问题

代码问题吧!我循环插入几万条数据 都没出问题:https://gitcafe.com/zhaop_roc/AtlasSpider-3/blob/master/groupon/proxy/coupon.js 代码第113行,也是用的new 和 save

试试把回调去掉!

new Already(a) 中有异步操作吗 感觉还是异步的问题

是的,这个问题确实是由异步操作引起的。在你的代码中,newAlready.save() 是一个异步操作,而 for 循环会立即执行完所有迭代,导致所有的回调函数在循环结束后才被执行。

为了解决这个问题,你可以使用 async 库或者 Promise 来管理异步操作。以下是两种解决方案:

使用 async

首先需要安装 async 库(如果还没有安装的话):

npm install async

然后你可以使用 async.each 或者 async.eachSeries 来顺序执行异步操作:

const async = require('async');

for (var i = 0; i < 10; i++) {
    var a = { seller_id: 1, order_id: 2 };
    console.log(i);
    const newAlready = new Already(a);
    async.eachSeries([i], function (index, callback) {
        newAlready.save(function (err, doc) {
            if (err) return callback(err);
            console.log(doc);
            callback();
        });
    }, function (err) {
        if (err) throw err;
    });
}

使用 Promiseasync/await

如果你更喜欢现代的 JavaScript 特性,可以使用 Promiseasync/await

function saveOrder(a) {
    return new Promise((resolve, reject) => {
        const newAlready = new Already(a);
        newAlready.save((err, doc) => {
            if (err) reject(err);
            else resolve(doc);
        });
    });
}

(async () => {
    for (let i = 0; i < 10; i++) {
        var a = { seller_id: 1, order_id: 2 };
        console.log(i);
        try {
            const doc = await saveOrder(a);
            console.log(doc);
        } catch (error) {
            console.error(error);
        }
    }
})();

这两种方法都可以确保每个 newAlready.save() 操作在前一个完成后才开始,从而避免异步问题。

回到顶部