回调NodeJS并用mongoose插入数据
Callback NodeJS & insert data with mongoose
我知道这个话题之前已经问过很多次了,但是我没有找到正确的答案来做我想做的事。
实际上,我尝试通过 Mongoose 在 MongoDB 中保存两个不同的 JSON 对象列表。为了同时执行两者,我使用 'async'。
但是,当我用命令 insertMany() 保存它时,我得到一个错误,因为他在完成 insertMany() 之前调用了异步的回调。因此 answer[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];
}
});
};
您的代码存在一些问题。首先,您没有在 createDataset
函数中 returning 任何东西。您在 insertMany
的回调中 returning 一个值,但它不会 return 该值给 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);
}
});
});
};
现在您的 return 对象不再是数组,因此您将无法通过 answer[0]
和 answer[1]
访问错误和结果。在调用 createDataset
并在 then
调用中使用 callback(null, answer)
之后,您需要链接一个 then
调用(因为这意味着 createDataset
执行成功)或者使用 callback(err)
如果 createDataset
抛出如下错误:
dataset: function(callback) {
setTimeout(function() {
utils.createDataset(datasetList).then(answer => {
callback(null, answer);
}).catch(err => callback(err)); // handle error here);
}, 100);
}
注意: 如果您的 createExp
代码也使用了异步函数,您很可能需要将其更改为在结构上与我上面生成的代码相似。
我知道这个话题之前已经问过很多次了,但是我没有找到正确的答案来做我想做的事。
实际上,我尝试通过 Mongoose 在 MongoDB 中保存两个不同的 JSON 对象列表。为了同时执行两者,我使用 'async'。 但是,当我用命令 insertMany() 保存它时,我得到一个错误,因为他在完成 insertMany() 之前调用了异步的回调。因此 answer[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];
}
});
};
您的代码存在一些问题。首先,您没有在 createDataset
函数中 returning 任何东西。您在 insertMany
的回调中 returning 一个值,但它不会 return 该值给 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);
}
});
});
};
现在您的 return 对象不再是数组,因此您将无法通过 answer[0]
和 answer[1]
访问错误和结果。在调用 createDataset
并在 then
调用中使用 callback(null, answer)
之后,您需要链接一个 then
调用(因为这意味着 createDataset
执行成功)或者使用 callback(err)
如果 createDataset
抛出如下错误:
dataset: function(callback) {
setTimeout(function() {
utils.createDataset(datasetList).then(answer => {
callback(null, answer);
}).catch(err => callback(err)); // handle error here);
}, 100);
}
注意: 如果您的 createExp
代码也使用了异步函数,您很可能需要将其更改为在结构上与我上面生成的代码相似。