Reputation: 1818
How can I execute many request in foreach without error please ?
Currently, I send a request on each entry on my array with foreach :
users.forEach(function (user) {
request({
url : 'myurl.com/api',
method: 'POST',
auth : {
'bearer': CONFIGURATION.auth.token
},
body : {
sender_id: user.sender_id
},
json : true
}, function (error, response, body) {
if (!error && response.statusCode === 200) {
resolve(body);
} else {
console.log('Error on coreService');
console.log('############### ERROR ###############');
console.log(error);
console.log('############### BODY ###############');
console.log(body);
console.log('############### RESPONSE ###############');
console.log(response);
reject(error);
}
});
});
With some request it's ok, but with some request I have this error :
Error on coreService
############### ERROR ###############
{ Error: connect ECONNRESET 127.0.0.1:80
at Object._errnoException (util.js:1022:11)
at _exceptionWithHostPort (util.js:1044:20)
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1198:14)
code: 'ECONNRESET',
errno: 'ECONNRESET',
syscall: 'connect',
address: '127.0.0.1',
port: 80 }
############### BODY ###############
undefined
############### RESPONSE ###############
undefined
Do you have an idea how can I fix this problem please ?
I tried with :
server.timeout = 0;
or
server.timeout = 1000;
but same problem...
If I execute the request, user by user, it's fine ! But with the foreach, it's break on some request...
Upvotes: 2
Views: 1902
Reputation: 989
In the comments colinux proposes that the connection reset errors are due to the server protecting itself from too many simultaneous requests, and I think they are probably correct. This code shows how you can use async/await to make your requests to the server one at a time. This might be too slow for you, but it could help you to confirm that the problem is as explained by colinux.
Here is another answer which does not require the use of request-promise-native and instead wraps the request calls in its own Promise.
const request = require('request');
const users = [{sender_id: 1}, {sender_id: 2}, {sender_id: 3}];
// make this driver function async so we can use await which allows waiting for
// a request to finish before starting the next one
async function runUserRequests() {
for (let i = 0; i < users.length; i++) {
const user = users[i];
try {
const response = await requestPromise(user);
console.log("response for user", user, response);
} catch (error) {
console.log("error for user", user, error);
}
};
}
// wrap the request call in a Promise so that it will run synchronously
function requestPromise(user) {
return new Promise(function(resolve, reject) {
request({
url: 'http://localhost:4000/',
method: 'GET', // method 'POST'
// auth : {
// 'bearer': CONFIGURATION.auth.token
// },
// body : {
// sender_id: user.sender_id
// },
// json : true
}, function (error, response, body) {
if (!error && response.statusCode === 200) {
resolve(body);
console.log("request successful for user", user, " at ", (new Date()).getTime());
} else {
console.log('Error on coreService');
console.log('############### ERROR ###############');
console.log(error);
console.log('############### BODY ###############');
console.log(body);
console.log('############### RESPONSE ###############');
console.log(response);
reject(error);
}
});
});
}
runUserRequests();
/*
Sample server used to test the code above:
const express = require('express')
const app = express()
const port = 4000
app.get('/', (req, res) => {
console.log("spinning for a bit");
setTimeout( () => {
console.log(" now responding");
res.send('Hello World!');
}, 1000);
});
app.listen(port, () => console.log(`Example app listening on port ${port}!`))
*/
Upvotes: 4
Reputation: 989
In the comments colinux proposes that the connection reset errors are due to the server protecting itself from too many simultaneous requests, and I think they are probably correct. This code shows how you can use async/await to make your requests to the server one at a time. This might be too slow for you, but it could help you to confirm that the problem is as explained by colinux.
To get this to work you'll need to install request-promise-native. If you can't do that let me know and I can work up an example wrapping the request api in your own Promise.
const request = require('request-promise-native');
//const users = [1, 2, 3, 4]; // dummy user array for testing
async function runUserRequests(users) {
for (let i = 0; i < users.length; i++) {
const user = users[i];
console.log("starting request for user ", user);
await request({
url: 'http://localhost:4000/',
method: 'GET',
auth : {
'bearer': CONFIGURATION.auth.token
},
body : {
sender_id: user.sender_id
},
json : true
}, function (error, response, body) {
if (!error && response.statusCode === 200) {
console.log("request successful for user", user, " at ", (new Date()).getTime());
resolve(body);
} else {
console.log('Error on coreService');
console.log('############### ERROR ###############');
console.log(error);
console.log('############### BODY ###############');
console.log(body);
console.log('############### RESPONSE ###############');
console.log(response);
reject(error);
}
});
};
}
runUserRequests();
Upvotes: 0