首页 > 解决方案 > 猫鼬和节点 js findOne 和更新查询承诺未在循环中解决

问题描述

我们正在尝试读取具有数据列表(大约 50K 对象)的目录下的大量 xml 文件,并在 DB 中检查每条记录,如果不存在则插入。完成一个文件数据后,它应该去第二个文件,这并不是所有的事情。下面是我们编写的代码。

仅供参考:我们最近开始研究 node、mongoose 并开始编写 cron 作业脚本。

    ## we recently starting working on node, mongoose and started writing a script the cron job.

    var fs = require('fs');
    function log(arg) {
        console.log(arg);
    }
     
    ## step-1: read the files in dir
    fs.readdir('./scripts/test/', function(err, files) {
        files.filter(fn => fn.endsWith('.xml')).forEach(file => {
            new Promise((resolve, reject) => {
                fs.readFile('/scripts/test/'+file, 'utf-8', (err, data) => {
                    if (!err) {
                        log('parsing XML to JSON.....');
                        resolve(data);
                    } else {
                        log('reading file error: '+err)
                        reject(err);
                    }
                });
            }).then((data) => {
                var productData = JSON.parse(data);
                ## calling another function
                format(productData);
            }).catch(err => log('Catch Error: '+err)); 
        });
    });

    async function format(items) {
        if (productData !== undefined) {
            await productBatchesloop(items);
            log('completed');
        } else {
            log('@@@@@@@ action:productData undefined @@@@@@@@');
        }
    }

    async function productBatchesloop(items) {
        var formatted_products, items_batch, promises;
        formatted_products = promises = []; var next = 1;

        var formatfn = function formatItems(product) {
            let pro = ProductModel.findOneAndUpdate(
                {id: product.id},
                product,
                {upsert: true, new: true, runValidators: true}).exec();
            pro.then((pro) => {
                log('inserted: '+pro.id);
            });
            log(pro);//not waiting for resolve, showing Promise <pending>
        }

        var res2 = Promise.all(items.map(formatfn));
        res2.then((data) => {
            log('*********** COMPLETED **************');
            // log(data);
        });
    }

标签: node.jsmongoose

解决方案


在 mongoose 查询中使用 async await。

var formatfn = async formatItems(product) => {
            let pro = await ProductModel.findOneAndUpdate(
                {id: product.id},
                product,
                {upsert: true, new: true, runValidators: true}).exec();
            pro.then((pro) => {
                log('inserted: '+pro.id);
            });
            log(pro);//not waiting for resolve, showing Promise <pending>
        }

推荐阅读