在setTimeout内使用insertMany和具有异步功能的for循环

时间:2018-10-11 12:07:36

标签: javascript node.js mongodb asynchronous mongoose

我正在尝试编写以下代码并使之同步工作,但这是唯一可以与console.log一起正常工作的问题,该问题会在1秒内延迟显示我数组中的每个项目,但不会使用以下结构:

for (let i = 0; i < array.length; i++) {
    setTimeout(function () {
        1.http request via rp or request.get (I receive a huge data array)
        2. .map results 
        3.insert to Mongo via mongoose 
     }
}

到目前为止,我内部包含以下代码:

request.get({url: array[i].url}), function (error, body) {
    body.map(element => {
        //do stuff, it works fine
     });
     collection.insertMany(body, function (err, docs) {
         //#justloggerthings
     }

或者我使用的是与rp而不是request.get几乎相同的版本 默认情况下,我有mongoose.Promise = global.Promise;

为什么这会引起问题?因为body.length是非常庞大的数据集,占用了大量RAM。 (现在想象20个带有insertMany的数组)

因此Mongo尝试一次insertMany来自请求的所有响应(准备就绪时,没有1000秒的延迟)。实际上,这就是为什么我选择request而不是rprequest-promise)的原因,但看起来也是如此。因此,我应该从npm中选择另一个http get模块并切换到该模块。不用担心吗?

还是应该包装此操作以保证||制作了一个异步函数,并在每次正确完成后每次(例如1000秒)在循环内调用它。在这种情况下,我在StackOverflow上发现的唯一实际内容是:

How to insert data to mongo synchronously (Nodejs, Express)

有点过时了。有什么想法吗?

2 个答案:

答案 0 :(得分:1)

好吧,我没有您的实际代码,所以我将用伪代码编写您可以做什么。

const chunkArray = (array, chunkSize) => {
    let i,j,chunks = [];
    for (i = 0, j = array.length; i < j; i += chunkSize) {
        chunks.push(array.slice(i, i + chunkSize));
    }
    return chunks;
}

for (let i = 0; i < array.length; i++) {
    let bigArray = await request('your data url');
    // do some mapping or whatever
    // then break your large array into smaller chunks
    let chunks = chunkArray(bigArray, 10);
    let j;
    for (j = 0; j < chunks.length; j++) {
        await collection.insertMany(chunks[j]);
    }

}

答案 1 :(得分:0)

解决我的问题的实际代码是:

async function test (name, url, lastModified) {
    try {
        const response = await rp({uri: url, json: true});
        response.map(async (element) => {
            if (element.buyout > 0) {
                element.price = (element.buyout / element.quantity);
            }
            element.lastModified = lastModified
        });
        return collection.insertMany(response);
    } catch (err) {
        console.error(err)
    }
}

async function addAsync() {
    const z = await test();
    console.log(z);
}

addAsync();