【问题标题】:Node js promise inside for loop always prints Promise { <pending> }for 循环中的节点 js 承诺总是打印 Promise { <pending> }
【发布时间】:2020-08-13 01:30:37
【问题描述】:

我正在尝试解决节点 js 中 for 循环内的承诺。在我的代码中,我有一个 for 循环,在其中我调用了一个函数 findincollection,它返回一个承诺。然后我将数据推送到finalresult 数组,并在 for 循环完成后解析它。但我面临的问题是它不能解决完整的数据。在解决所有承诺之前,for 循环执行已完成。 console.log(p1); 行总是打印 Promise { } 但它最终会得到解决,正如您在 p1.then() 语句中的代码中看到的那样,我确实得到了数据。但是finalresult 数组解析得太早了。我也想知道为什么我总是得到 Promise { } 即使承诺最终仍然得到解决。 请看我下面的代码:

var mob = [123, 456, 789];
var list = [1, 2, 3, 4, 5, 6, 7, 8];
var res = [];
var finalresult = [];
for (y = 0; y < list.length; y++) {
    const p1 = findincollection(list[y], mob, savetofile);
    console.log(p1); //always prints Promise { <pending> } 8 times
    p1.then(function(dt) {
        finalresult.push(dt); //pushes all 3 objects one by one
        console.log(dt); //prints 3 objects one by one
        client.close();
        if (y == (collist.length)) { //check if the loop has reached the last index
            resolve(finalresult); //resolves the finalresult array with 1 object only instead of 3. I want this part to resolve the complete finalresult array i.e with all 3 objects.
        }
    });
}

const findincollection = function(index, mob, save) {
    return new Promise((resolve, reject) => {
        MongoClient.connect(url, function(err, client) {
            assert.equal(null, err);
            const db = client.db(dbName);
            const collection = db.collection(col);
            collection.find({ 'Numbers': { $in: mob } }).toArray(function(err, docs) {
                const c = save(index, docs);
                c.then(function(m) {
                    console.log(m); //print's Saved 3 times as the mob array length is 3
                    client.close();
                    return resolve(res);
                })
            });
        });
    });
}

const save = function(index, data) {
    return new Promise((resolve, reject) => {
        if (data.length > 0) {
            for (var k = 0; k < data.length; k++) {
                res.push(data[k]);
            }
            fs.appendFile('textlogs/' + index + '.txt', data, function(err) {
                if (err) throw err;
                resolve('Saved');
            });
        }
    });
}

我无法弄清楚如何让循环等到所有承诺都得到解决或使代码同步然后只解决finalresult 数组?我该怎么做?

【问题讨论】:

  • 打印挂起,因为它是挂起的?您的代码还假设最后一个承诺将最后解决
  • @sinanspd 我试过 promise.all() 但它仍然没有按预期工作。
  • @Jaromanda X 你能帮我弄清楚我的代码有什么问题吗?
  • 将你的 findincollection(list[y], mob, savetofile) 推送到一个数组,然后 promise.all 那个数组。还有为什么你要多次连接你的mongodb,你为什么不在开始时或服务器启动时连接一次?

标签: javascript node.js promise


【解决方案1】:

您需要的是Promise.all()。它返回一个新的 Promise,一旦所有通过的 Promise 得到解决,它就会被解决。

您可以尝试类似的方法:

var promises = [];

for (y = 0; y < list.length; y++) {
    promises.push(findincollection(list[y], mob, savetofile));
}

Promise.all(promises)
   .then(dt => {
       finalresult.push(dt); //pushes all 3 objects one by one
       console.log(dt); //prints 3 objects one by one
       client.close();
       if (y == (collist.length)) { 
           resolve(finalresult);
       }
   }); // <-- this will be raised once all your promises are resolved

我看到您在每个承诺中都关闭了客户端,并且该客户端不是局部变量。所以我认为你应该在完成所有承诺后关闭它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-07-26
    • 2019-08-17
    • 2017-11-01
    • 2023-03-17
    • 2021-11-01
    • 2015-12-18
    • 2016-10-11
    • 2018-09-26
    相关资源
    最近更新 更多