代码之家  ›  专栏  ›  技术社区  ›  AlexZeDim

带有异步函数的setTimeout和for循环中的insertMany

  •  0
  • AlexZeDim  · 技术社区  · 6 年前

    我正在尝试编写以下代码并使其同步工作,但唯一的问题是它工作正常 console.log

    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 是一个非常大的数据集,它吃掉了很多公羊(现在想象20+个数组 insertMany

    所以Mongo想 请求的所有响应立即生效(准备就绪时,无1000秒延迟)。事实上这就是我选择的原因 request ( request-promise )但它看起来也是异步的。那么我应该从中选择另一个httpget模块吗 npm 然后切换到它。不用担心?

    或者我应该包装这个操作来保证| |生成一个异步函数,并在每次正确完成时(例如1000秒)在循环中调用它。在这种情况下,我在StackOverflow上发现的唯一实际情况是:

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

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

    2 回复  |  直到 6 年前
        1
  •  1
  •   Rainer Plumer    6 年前

    好吧,我没有你的实际代码,所以我会写在伪代码你可以做什么。

    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]);
        }
    
    }
    
        2
  •  0
  •   AlexZeDim    6 年前

    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();