使用nodejs在foreach中进行多个http发布

时间:2019-06-23 12:47:16

标签: javascript node.js request

请问如何在foreach中执行许多请求而不会出现错误?

当前,我使用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);
        }
    });
});

有一些请求没关系,但是有一些请求我有此错误:

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

您知道如何解决此问题吗?

我尝试过:

  

server.timeout = 0;

  

server.timeout = 1000;

但同样的问题...

如果我逐个用户执行请求,就可以了! 但是有了foreach,它在某些请求上就中断了...

2 个答案:

答案 0 :(得分:2)

在评论中,colinux提出连接重置错误是由于服务器保护自己免受太多同时请求的影响,我认为它们可能是正确的。这段代码显示了如何使用async / await一次向服务器发出一个请求。这可能对您来说太慢了,但是它可以帮助您确认问题是否与colinux解释的一样。

这是另一个答案,它不需要使用request-promise-native,而是将请求调用包装在自己的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}!`))

*/


答案 1 :(得分:0)

在评论中,colinux提出连接重置错误是由于服务器保护自己免受太多同时请求的影响,我认为它们可能是正确的。这段代码显示了如何使用async / await一次向服务器发出一个请求。这可能对您来说太慢了,但是它可以帮助您确认问题是否与colinux解释的一样。

要使其正常工作,您需要安装request-promise-native。如果您无法做到这一点,请告诉我,我可以整理一个示例,将请求api包装在您自己的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();