节点CSV文件上传同步导入,然后执行猫鼬查找

时间:2019-02-22 03:26:35

标签: node.js promise

成功上传csv文件后,我无法从猫鼬查找查询中获得结果。来自csvs的数据被保存在我的收藏集中。但是以下查找查询没有任何结果。是什么原因导致诺言不符合顺序?我觉得我可能已经接近了解诺言,因为它们是在事件循环中处理的,但是这种情况使我无法逃脱?

let uploadfiles = function (req,res) {
 return new Promise( function (resolve, reject) {
    upload(req, res, (err) => {
        promises = [];
        if (!err) {
            if (Object.keys(req.files).length>0) {

                simpleLoop(req.files, function (value, key, lovey) {
                    promises.push(insertStreamData(req.files[key]["originalname"]));
                });

                      console.log('hither');


            }
        }
              return Promise.all(promises);

    });
    resolve('something');
     });
   };



// insert uploaded csv data from files into db 
function insertStreamData(filename){
    var originalFileName = filename;
    var thefilename = originalFileName.split('.');
    var csvfile = "./public/files/"+originalFileName;
    var stream = fs.createReadStream(csvfile, { headers: true});

    var csvStream = csv().on("data", function(data){

        if(data[0] != 'Product #' && data[7] != 0){
            var item = new Product({
                'Invoice':thefilename[0],
                'Product #': data[0],
                'SKU': data[1],
                'UpcCode': data[2],
                'Description': data[3],
                'MfgNo': data[4],
                'Vendor': data[5],
                'Order Qty': data[6],
                'Ship Qty': data[7],
                'Min Sell': data[8],
                'Retail': data[9],
                'Cost': data[10],
                'Ext Cost': data[11],
                'Box': data[12]

            });


            item.save(function(error){ if(error){ throw error; } });

        }
    }).on("end", function(){
        console.log('the end');
    });
    stream.pipe(csvStream);
}






let getincomingproducts =  function(){
 return new Promise(function (resolve, reject) {

 resolve('done');


 });
};

router.post('/uploaddata', function(req, res) {


    uploadfiles(req,res).then(function(result){
      return getincomingproducts();
    }).then(function(result){
      console.log(result);
      res.redirect('/showdata');

    }).catch(err => console.log("Caught " + err));





});

在第一个承诺之前,输出“完成”已记录到控制台。我想用猫鼬代替完成查找结果。但是一个简单的控制台日志显示了不同步的结果。

done
hither
the end
the end
the end
the end

1 个答案:

答案 0 :(得分:0)

请不要将Promise构造函数等与async和await混合使用。如果仅使用await和async函数,则可能会容易得多。并且仅将回调接受函数包装一次。

一个干净的版本在Promise构造函数中没有任何业务逻辑,而是使用await而不是异步函数。

我在程序中发现了第二点,它不等待动作完成,即insertStreamData不返回完成时实现的诺言,这是导致乱序问题的原因。我将更新答案。

我在上传文件时发现了一个问题:

return Promise.all(promises);

    });
    resolve('something');

应为

return Promise.all(promises).then(function () {
  resolve('something');
});

此更改应导致输出为hither, the end * 4, done。如果希望insertStreamData以串行方式而不是并行方式出现,则需要进行其他更改。


我的脚本版本:

function upload_wrapper(req, res) {
  return new Promise(function(resolve, reject) {
    upload(req, res, function (err) {
      if (err) {
        reject(err);
      } else {
        resolve();
      }
    });
  })
}


let uploadfiles = async function(req, res) {
  await upload_wrapper(req, res);
  let promises = [];
  if (Object.keys(req.files).length > 0) {
    simpleLoop(req.files, function(value, key, lovey) {
      promises.push(insertStreamData(req.files[key]["originalname"]));
    });
    console.log('hither');
  }
  await Promise.all(promises);
  return 'something';
};


// insert uploaded csv data from files into db 
function insertStreamData(filename) {
  return new Promise(function(resolve, reject) {

    var originalFileName = filename;
    var thefilename = originalFileName.split('.');
    var csvfile = "./public/files/" + originalFileName;
    var stream = fs.createReadStream(csvfile, {
      headers: true
    });
    var csvStream = csv();

    csvStream.on("data", function(data) {

      if (data[0] != 'Product #' && data[7] != 0) {
        var item = new Product({
          'Invoice': thefilename[0],
          'Product #': data[0],
          'SKU': data[1],
          'UpcCode': data[2],
          'Description': data[3],
          'MfgNo': data[4],
          'Vendor': data[5],
          'Order Qty': data[6],
          'Ship Qty': data[7],
          'Min Sell': data[8],
          'Retail': data[9],
          'Cost': data[10],
          'Ext Cost': data[11],
          'Box': data[12]
        });

        item.save(function(error) {
          if (error) {
            //throw error;
            csvStream.pause(); // here the stream should be destroyed if this stops at the first error
            reject(error);
          }
        });
      }
    }).on("end", function() {
      console.log('the end');
      resolve('the end');
    });
    stream.pipe(csvStream);

  });
}

let getincomingproducts = function() {
  return Promise.resolve('done');
};

router.post('/uploaddata', async function(req, res) {

  try {
    let result = await uploadfiles(req, res);
    let result = await getincomingproducts();
    console.log(result);
    res.redirect('/showdata');
  } catch (err) {
    console.log("Caught " + err)
  }

});

未经测试。仍然可以改进。