2016-08-18 63 views
0

我無法使用簡單的for循環,因爲request.save是一個函數。所以我嘗試了每個。它完美的工作!在我添加request.save部分之前,我收到以下錯誤消息,它會中斷我的應用程序。跨陣列在Node.JS中迭代保存

錯誤:發送後無法設置標題。

exports.submit = function (req, res) { 


    Person.find({ 
     cellPhone: req.body.phone 
    }).exec(function (err, people) { 
     people.forEach(saveRequest); 
    } 

    function saveRequest(item, index) { 

     var request = new Requests(); 
     request.start = req.body.start.value; 
     request.finish = req.body.finish.value; 
     request.phone = req.body.phone; 
     request.offDay = req.body.date; 

     request.user = people[index]._id; 
     request.name = people[index].name; 
     request.group = people[index].group; 

     request.save(function (err) { 
      if (err) { 
      console.log('request.save'); 
      return res.status(400); 
      } else { 
      // Remove sensitive data before login 
      //user.password = undefined; 
      //user.salt = undefined; 
      console.log(request); 
      res.json(request); 
      } 
     }); 
    } 
}); 
+0

你不能多次調用'res.json',你應該使用res.write。由於保存是異步的,我認爲最好是使用Promise –

+0

謝謝!代碼應該是什麼樣子?我試過res.writeHead(200,{'Content-Type':'text/plain'});我嘗試了res.write(200,{'Content-Type':'text/plain'});多次,他們都打破了應用程序。 –

回答

1

問題是,當你執行.save()傳遞一個匿名函數完成錯誤的情況下的響應。

因此,您完成第一個保存事件錯誤。

您應完成保存回調以外的響應。

也許使用事件來同步你的代碼,或更好的發電機。

您forEach循環之前:

let savedResponses = []; 
let savedErrors = []; 
... 

那麼你savedRequest:

function saveRequest(item, index) { 

    var request = new Requests(); 
    request.start = req.body.start.value; 
    request.finish = req.body.finish.value; 
    request.phone = req.body.phone; 
    request.offDay = req.body.date; 

    request.user = people[index]._id; 
    request.name = people[index].name; 
    request.group = people[index].group; 

    request.save(function (err) { 
     if (err) { 
      console.log('request.save error'); 
      savedErrors.push(err); 
      // return res.status(400); 
     } else { 
      // Remove sensitive data before login 
      //user.password = undefined; 
      //user.salt = undefined; 
      console.log(request); 
      savedResponses.push(request); 

     } 
    }); 

} 

然後foreach循環後,應等待在.save異步工作人員結束()回調。

您可以使用事件包或生成器或承諾模式。

它取決於您節點的版本。

當你的代碼同步的,你可以只完成你的第一反應檢查錯誤:

if (savedErrors.length > 0) { 
    res.status = 400; 
    // ... report errors 
} 

或者只是完成與savedResponses的響應。

+0

我將刪除保存函數中的響應,並在foreach後面直接添加它 –

+0

如果這樣做,則無法保證所有保存都是**異步**。正如我在評論中所說的,你絕對應該在Promise.all中使用Promises –

+0

@ oliv37我在答覆中寫道,應該以某種方式處理ascynchronous部分。 –