我试着编写这段代码非常简单,专注于解决问题,但我真正想要的是一个nodejs控制器多次调用另一个更高级的nodejs控制器。
这是我的路线
// test Route
var express = require('express');
var router = express.Router();
var testController = require('../controllers/testController');
router.get('/getTest', function(req, res) {
testController.getTest(req, res);
});
module.exports = router;
这是我的 testController.js
exports.getTest = function(req, res) {
var myArray = [300,200,400,100,500];
var myResult = [];
// Find all data based on myArrau
var findData = function() {
return new Promise((resolve, reject) => {
for (var i=0; i<myArray.length; i++) {
callDataController(i, myArray[i]);
}
resolve();
})};
// Call and get the specific data
var dataController = require('./dataController');
var callDataController = function(i, myValue) {
return new Promise((resolve, reject) => {
dataController.getData (
{ "myValue": myValue }, res,
function(err, data) {
if (!err) {
myResult[i] = data;
resolve(data);
} else {
reject(new Error('ERR dataController: ' + err));
};
});
})};
// Send result to page
var sendResult = function(data) {
return new Promise((resolve, reject) => {
res.json({error:false, "myResult":myResult})
resolve();
});
};
// Run promises
findData()
.then(sendResult)
.catch(err => {
console.log("getTest ERR: " + err);
res.json({error:true,err})
}
)
}
这是我的 dataController ,通常会做很多mongodb工作
exports.getData = function(req, res) {
console.log("Data received: " + JSON.stringify(req, null, 4));
console.log("Doing lots of mongodb work taking milliseconds to minutes")
setTimeout(function(){},req.myValue);
res.json({error:false, "myValue":req.myValue+1000 })
}
这就是问题所在,最好由终端console.log
解释Data received: {
"myValue": 300
}
Do a LOT of mongodb work taking anywhere from milliseconds to minutes
Data received: {
"myValue": 200
}
Do a LOT of mongodb work taking anywhere from milliseconds to minutes
Data received: {
"myValue": 400
}
Do a LOT of mongodb work taking anywhere from milliseconds to minutes
Data received: {
"myValue": 100
}
Do a LOT of mongodb work taking anywhere from milliseconds to minutes
Data received: {
"myValue": 500
}
Do a LOT of mongodb work taking anywhere from milliseconds to minutes
GET /testRoute/getTest 304 8.448 ms - -
getTest ERR: Error: Can't set headers after they are sent.
(node:9976) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): Error: Can't set headers after they are sent.
(node:9976) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 2): Error: Can't set headers after they are sent.
(node:9976) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 3): Error: Can't set headers after they are sent.
(node:9976) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 4): Error: Can't set headers after they are sent.
(node:9976) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 6): Error: Can't set headers after they are sent.
即使我只在myArray中放入一个值,我仍然会收到错误:发送后无法设置标题。
这是异步的一点,我无法开始工作。 (已经尝试将它们全部添加到Promise.all数组中,同样的问题)
答案 0 :(得分:1)
您的问题是,您多次呼叫的控制器正在将响应写入客户端 - 多次(或至少,它正在尝试)。相反,让它只返回一个承诺,并仅在路由器代码中响应:
// test Route
var express = require('express');
var router = express.Router();
var testController = require('../controllers/testController');
router.get('/getTest', function(req, res) {
testController.getTest(req).then(function sendResult(myResult) {
res.json({error:false, "myResult":myResult}))
}, err => {
console.log("getTest ERR: " + err);
res.json({error:true,err});
});
});
module.exports = router;
// testController.js
var dataController = require('./dataController');
exports.getTest = function(req) {
var myArray = [300,200,400,100,500];
var myResult = [];
// Find all data based on myArrau
function findData() {
return myArray.map(callDataController);
}
// Call and get the specific data
function callDataController(myValue, i) {
return dataController.getData (
{ "myValue": myValue }
).catch(function(err) {
throw new Error('ERR dataController: ' + err)
});
};
// Run promises
return Promise.all(findData());
}
// dataController
exports.getData = function(req) {
return new Promise((resolve, reject) => {
console.log("Data received: " + JSON.stringify(req, null, 4));
console.log("Doing lots of mongodb work taking milliseconds to minutes")
setTimeout(function(){
resolve({error:false, "myValue":req.myValue+1000 });
}, req.myValue);
});
};