Node.js异步数组保存数据到mongodb

node.js async array save data to mongodb

本文关键字:数据 mongodb 保存 数组 js 异步 Node      更新时间:2023-09-26

我有一个字符串

var my_str = "Jenny [id:51], david, Pia [id:57], Aston [id:20], Raj, ";

我将此发送到函数convert_to_array(my_str),并希望这样的东西返回

[all: [51, 72, 57, 20, 73], new: [72, 73]]

这里,72 &73个新插入的文档到mongodb数据库。

这就是我正在做的:

function convert_to_array(text) {
if(text && text !== '') {
    var text_arr = text.split(', ');
    text_arr.pop();
    var arr = new Array();
    var new_profiles = new Array();
    var all_profiles =  new Array();
    for(var i = 0; i < text_arr.length; i++) {
        var pair = text_arr[i].split('[id:');
        // Its already existing, just add it to the array
        if(pair[1]) {
            all_profiles.push(pair[1].split(']')[0]);
        // Else create a new profile and pass the _id
        } else {
            // Save to db first
            var profileObj = new Profile({name: pair[0], automated: true});
            profileObj.save(function(err, data) {
                if(err) throw err;
                all_profiles.push(String(data._id));
                new_profiles.push(String(data._id));
            });
        }
    }
    arr = {all: all_profiles, new: new_profiles};
    return arr;
}
}

使用这段代码,我只得到这个(或类似的东西,我不记得确切的输出)

    [all: [51, 57, 20], new: []]

项目保存在数据库中,我可以看到。但由于node本质上是非阻塞的,因此for循环在数据保存到数据库&并将id推入数组。我尝试了async,但仍然无法解决这个问题。

我添加了一些控制台。查看它的执行情况,如下所示:

yes existing: 51
oh! doesnt exist. creating: david
yes existing: 57
yes existing: 20
oh! doesnt exist. creating: Raj
GET /page/delete_later 200 4ms
Ok created now: 72
Ok created now: 73

我很困惑如何编码它的节点友好!

您需要更改您的convert_to_array函数,以便在结果完成时调用回调,而不是返回结果返回值。

function convert_to_array(text, callback) {
   // do some stuff, call this when done:
   //    callback(null, arr);
   // or this on error:
   //    callback(err);
}

现在你的结果准备好了吗?当所有text_arr项都被处理时(即所有对profileObj.save的调用都完成)。可能在代码中表达这一点的最简单方法是使用async模块(npm install async):

var async = require('async');
// ...
function convert_to_array(text, callback) {
  if(text && text !== '') {
    var text_arr = text.split(', ');
    text_arr.pop();
    var arr = new Array();
    var new_profiles = new Array();
    var all_profiles =  new Array();
    async.eachSeries(text_arr, function(it, done) {
      var pair = text_arr[i].split('[id:');
      // Its already existing, just add it to the array
      if(pair[1]) {
        all_profiles.push(pair[1].split(']')[0]);
        next(); // !important! tell async we are done
      // Else create a new profile and pass the _id
      } else {
        // Save to db first
        var profileObj = new Profile({name: pair[0], automated: true});
        profileObj.save(function(err, data) {
            if(err) {
              // throw err; // use callback instead of throw for error handling
              next(err);
              return;
            }
            all_profiles.push(String(data._id));
            new_profiles.push(String(data._id));
            next(); // !important! tell async we are done
        });
    }, function(err) { 
      arr = {all: all_profiles, new: new_profiles};
      callback(err, arr);
    }
  } else {
    callback(null, undefined); // alter depending on your requirements
  }
}