2015-10-14 42 views
0

在我的代碼中,onResolve()函數在第一個函數之後被調用,在任何其他函數之前(當req.body.length> 1時看到它)。任何想法爲什麼?我想將保存的資產列表添加到數組中,然後在所有findOneAndUpdate執行完成後在響應中發送該數組。mongoose mpromise onResolve before before before

exports.saveAssetLists = function(req, res) { 
    console.log('starting save asset lists'); 
    if (!Common.testIfValidForSave(req.body, true)) { 
    res.status(400).send({error:'Invalid request body: ' + JSON.stringify(req)}); 
    return; 
    } 

    var deferred = null; 
    var savedAssetLists = []; 
    for (var i = 0; i < req.body.length; i++) { 
    var newAssetList = new AssetList(req.body); 
    var d = AssetList.findOneAndUpdate({_id: newAssetList._id }, newAssetList, {upsert:true, new:true}).exec().then(function(obj) { 
     console.log('then - obj: ' + JSON.stringify(obj)); 
     savedAssetLists.push(obj); 
    }); 
    if (!deferred) { 
     deferred = d; 
    } else { 
     deferred.chain(d); 
    } 
    } 
    deferred.onResolve(function(err, result) { 
    console.log('onResolve - err: ' + err + ', result: ' + result + ', savedAssetLists: ' + savedAssetLists); 
    res.send({data: savedAssetLists}); 
    }) 
    .onReject(function(err) { 
    res.status(500).send({error: err}); 
    }); 
    return deferred; 
}; 

這是日誌輸出:

starting save asset lists 
then - obj: {"_id":"561eafe95c0df2c0468cb798","name":"Asset List 1","__v":0,"assets":[null]} 
onResolve - err: null, result: undefined, savedAssetLists: { _id: 561eafe95c0df2c0468cb798, 
    name: 'Asset List 1', 
    __v: 0, 
    assets: [ null ] } 
then - obj: {"_id":"561eafe95c0df2c0468cb799","name":"Asset List 2","__v":0,"assets":[null]} 

按照從梅耶一個建議,我改變了我的代碼以下,但當時的方法不會被調用:

exports.saveAssetLists = function(req, res) { 
    console.log('starting save asset lists'); 
    if (!Common.testIfValidForSave(req.body, true)) { 
    res.status(400).send({error:'Invalid request body: ' + JSON.stringify(req)}); 
    return; 
    } 

    var promises = []; 
    var savedAssetLists = []; 
    for (var i = 0; i < req.body.length; i++) { 
    var newAssetList = new AssetList(req.body[i]); 
    var p = AssetList.findOneAndUpdate({_id: newAssetList._id }, newAssetList, {upsert:true, new:true}).exec(); 
    promises.push(p); 

    } 
    Promise.all(promises).then(function(values) { 
    console.log('onResolve - err: ' + err + ', values: ' + values + ', savedAssetLists: ' + savedAssetLists); 
    res.send({data: values }); 
    }, function(err) { 
    res.status(500).send({error: err}); 
    }); 
}; 
+0

爲什麼你需要這樣一個複雜的調用,如果你可以使用只是得到一堆承諾,把它們推到'Promise.all'並在裏面得到結果呢? –

+0

很好的問題。根據我的控制檯,mongoose.Promise.all()不存在 – user1387717

+0

它不是'mongoose.Promise.all',它只是'Promise.all'。我會做出回答 –

回答

0

你可以做的是在req.body之外創建一系列承諾:

var promises = req.body.map(function(data){ 
    var newAssetList = new AssetList(data); 
    return AssetList.findOneAndUpdate({_id: newAssetList._id }, newAssetList, {upsert:true, new:true}) 
}); 

Promise.all(promises).then(function(results){ 
    return res.send({data: results}); 
}).catch(function(err){ 
    return res.status(500).send({error: err}); 
}); 

小記:代碼中不需要mpromise庫。這應該適用於貓鼬4+

+0

嗨,謝謝你的答案。我做了幾乎相同的(幾乎),然後函數永遠不會被調用(請參閱我上面的編輯) – user1387717

+0

您不需要調用'exec'作爲'findOneAndUpdate'返回一個承諾。試試我的代碼 –

+0

謝謝!你的代碼工作!雖然我不明白爲什麼我沒有刪除.exec()語句之後甚至沒有。 – user1387717