2016-06-28 43 views
1

我有以下代碼來填充我的測試數據庫。目標是在每個子文檔之後將父文檔保存到父文檔中,以便對其進行引用。如何管理Node.js異步變量作用域?

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 
} 

我已經嘗試了一些這方面的變化,我認爲它與變量範圍有關。然而,我想通過深度複製我的obj var obj = Object.assign({},objs [i])會保存對象的「真實」副本,以便以後在異步函數中使用。

根據其中許多辦法,我已經盡力使這項工作我結束了以下錯誤之一:

TypeError: obj.save is not a function

TypeError: Cannot read property 'save' of undefined

我已經看到了一些談使用.bind()來控制可變範圍,但我不知道如何在這種情況下使用它。

+1

哪些成分和方向變量傳遞給createSaveTasks? –

+0

Mongoose模型對象的數組,其中包含一個保存功能。如果我將成分[0] .save()作爲saveRecipe()的第一個函數,則此成分將保存在數據庫中。 (只是試圖驗證它的工作) –

+1

好吧,如果你在createSaveTask函數的循環中記錄objs [i]會發生什麼? –

回答

2

Bind返回一個新函數,您可以指定分配給函數的上下文(在函數內調用「this」關鍵字時獲得的值)和/或傳遞給該函數的參數。 Bind(thisArg, ...arguments)。所以你的情況:

var saveTask = function(callback){this.save(...)}.bind(obj[i])

有了這個,你指定的範圍內,因此在該函數的對象將是入店爲this。 一些例子:

(function a(){console.log(this)}).bind({key : 'value'})(); 
 

 
var a = function(){console.log(this)}.bind({key : 'value'}); 
 
a();