【发布时间】:2016-06-29 06:25:55
【问题描述】:
我有以下代码用于填充我的测试数据库。目标是在每个子文档对父文档都可以引用它们之后保存父文档。
function saveRecipe(ingredients, directions, recipe, done) {
var ingredientSaveTasks = createSaveTasks(ingredients)
var directionSaveTasks = createSaveTasks(directions)
async.parallel([
(callback) => { async.series(ingredientSaveTasks, callback) },
(callback) => { async.series(directionSaveTasks, callback) }
], (err, results) => {
recipe.ingredients = results[0] // The returned ids for each ingredient
recipe.directions = results[1] // The returned ids for each direction
recipe.save(done)
})
}
function createSaveTasks(objs) {
var saveTasks = []
for (var i = 0; i < objs.length; i++) {
var saveTask = function (callback) {
var obj = Object.assign({}, objs[i])
obj.save((err, result) => {
callback(err, result._id)
})
}
saveTasks.push(saveTask)
}
return saveTasks
}
我已经尝试了一些变体,我认为这与变量范围有关。但是,我认为通过使用 var obj = Object.assign({}, objs[i]) 深度复制我的 obj 可以保存对象的“真实”副本以供以后在异步函数中使用。
根据我尝试完成这项工作的多种方式中的哪一种,我最终会遇到以下错误之一:
TypeError: obj.save 不是函数
TypeError: 无法读取未定义的属性“保存”
我看到一些关于使用 .bind() 控制变量范围的讨论,但我不确定在这种情况下如何使用它。
【问题讨论】:
-
传递给 createSaveTasks 的成分和方向变量是什么?
-
Mongoose 模型对象数组,其中包含保存功能。如果我把配料[0].save() 作为 saveRecipe() 的第一个函数,这个配料就会保存在数据库中。 (只是尝试验证它是否有效)
-
好的,如果你在 createSaveTask 函数的循环中记录 objs[i] 会发生什么?
-
好吧,正如您所说的,bind 是解决方案,bind 返回一个新函数,您可以在其中指定分配给函数的上下文(在函数内部调用“this”关键字时获得的值)和/或传递给函数的参数。因此,在您的情况下 var saveTask = function(callback){this.save(...)}.bind(obj[i]) 使用 this 指定上下文,因此在该函数中,您的对象将可以作为 "this"
-
这很完美!现在我明白了 bind 做了什么,重新定义了你所说的“this”关键字。非常感谢,只需复制/粘贴您的答案,我会接受。 :-)
标签: javascript node.js async.js