我知道这个话题已经被问过很多次了,但是我没有找到正确的答案来做我想做的事情。
实际上,我尝试通过Mongoose在MongoDB中保存两个不同的JSON对象列表。要同时执行两个操作,请使用“异步”。
但是,当我使用命令insertMany()保存它时,出现错误,因为他在完成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];
}
});
};
最佳答案
您的代码有一些问题。首先,您没有在createDataset
函数中返回任何内容。您正在insertMany
的回调中返回一个值,但它不会将该值返回给createDataset
的调用者,因为它在另一个作用域之内。要解决此问题,您可以将Dataset.insertMany
包装在promise中,并根据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
如下错误:dataset: function(callback) {
setTimeout(function() {
utils.createDataset(datasetList).then(answer => {
callback(null, answer);
}).catch(err => callback(err)); // handle error here);
}, 100);
}
注意:如果还使用异步功能,则很可能需要更改
createExp
代码,使其在结构上类似于我上面生成的代码。