Обратный вызов NodeJS и вставка данных с помощью mongoose - PullRequest
0 голосов
/ 24 июня 2018

Я знаю эту тему, как уже задавали много раз прежде, но я не нашел правильного ответа, чтобы делать то, что я хочу.

На самом деле, я пытаюсь сохранить два разных списка объекта JSON в MongoDB через Mongoose,Для выполнения обоих одновременно я использую 'async' .Однако, когда я сохраняю его с помощью команды insertMany () , я получаю сообщение об ошибке, потому что он вызывает обратный вызов async перед завершением операции insertMany ().Поэтому ответ [0] не определен.

Каким будет правильный способ сделать это?

Вот мой код с асинхронностью:

const mongoose = require("mongoose");
const async = require("async");
const utils = require("../utils");

const experimentCreate = function(req, res) {
  let resData = {};
  let experimentList = req.body.experiment;
  let datasetList = req.body.datasetList;

  async.parallel(
        {
          dataset: function(callback) {
            setTimeout(function() {
              answer = utils.createDataset(datasetList);
              callback(answer[0], answer[1]);
            }, 100);
          },
          experiment: function(callback) {
            setTimeout(function() {
              answer = utils.createExp(experimentList);
              callback(answer[0], answer[1]);
            }, 100);
          }
        },
        function(err, result) {
          if (err) {
            console.log("Error dataset or metadata creation: " + err);
            sendJSONresponse(res, 404, err);
          } else {
            console.log("Experiment created.");
            resData.push(result.dataset);
            resData.push(result.experiment);
            console.log(resData);
            sendJSONresponse(res, 200, resData);
          }
        }
      );
};

Тогдадве функции с именами createExp и createDataset совпадают в другом файле.Как это:

const createDataset = function(list) {
  let datasetList = [];
  for (item of list) {
    let temp = {
      _id: mongoose.Types.ObjectId(),
      name: item.name,
      description: item.description,
      type: item.type,
    };
    datasetList.push(temp);
  }

  Dataset.insertMany(datasetList, (err, ds) => {
    if (err) {
      console.log("Error dataset creation: " + err);
      return [err, null];
    } else {
      console.log("All dataset created.");
      return [null, ds];
    }
  });
};

1 Ответ

0 голосов
/ 24 июня 2018

Есть несколько проблем с вашим кодом.Например, вы ничего не возвращаете в своей функции createDataset.Вы возвращаете значение в обратном вызове insertMany, но оно не возвращает это значение вызывающей стороне createDataset, поскольку оно находится в другой области видимости.Чтобы решить эту проблему, вы можете заключить ваше Dataset.insertMany в обещание и разрешить или отклонить в зависимости от результата Data.insertMany, например:

const createDataset = function(list) {
  let datasetList = [];
  for (item of list) {
    let temp = {
      _id: mongoose.Types.ObjectId(),
      name: item.name,
      description: item.description,
      type: item.type,
    };
    datasetList.push(temp);
  }

  return new Promise((resolve, reject) => {
    Dataset.insertMany(datasetList, (err, ds) => {
      if (err) {
        console.log("Error dataset creation: " + err);
        reject(err);
      } else {
        console.log("All dataset created.");
        resolve(ds);
      }
    });
  });   
};

Теперь ваш возвращаемый объект больше не будетмассив, так что вы не сможете получить доступ как к ошибке, так и к результату через answer[0] и answer[1].Вам нужно будет соединить вызов then после вызова createDataset и использовать callback(null, answer) в вызове then (это означает, что createDataset успешно выполнен) или использовать callback(err), если createDataset throwsошибка, подобная приведенной ниже:

dataset: function(callback) {
  setTimeout(function() {
    utils.createDataset(datasetList).then(answer => {
      callback(null, answer);
    }).catch(err => callback(err)); // handle error here);
  }, 100);
}

Примечание: Скорее всего, вам придется изменить свой код createExp, чтобы он был структурно похож на тот, что я создал выше, если он также используетасинхронные функции.

...