如何使用NodeJS在forEach中解决多个GET请求

时间:2019-06-14 17:22:52

标签: node.js promise es6-promise node-request

我想在JSON文件中使用许多股票报价器,以发送多个GET请求来获取该股票的价格。我遇到的问题是如何并行发送它们以及如何解决它们。

这是我尝试过的代码:

const stocks = require('./stocks.json')
var request = require("request");

    var stockTickers = stocks.map(x => x.stockopediaTicker)
    stockTickers.forEach(ticker => {
        var promises = []
        var options = {
            method: 'GET',
            url: 'https://www.stockopedia.com/ajax/get_prices/' + ticker + '/'
        };
        let todaysQuote = new Promise(function (res, rej) {
            request(options, function (error, response, body) {
                rej(error)
                res(body)
            });
        })
        promises.push(todaysQuote)
    });

    Promise.all(promises)
        .then((results) => {
            console.log(results)
        }).catch(err => console.log(err))

3 个答案:

答案 0 :(得分:0)

您应该检查是否存在错误,并且仅检查rej是否存在错误:

let todaysQuote = new Promise(function (res, rej) {
        request(options, function (error, response, body) {
            if(error) {
                return rej(error)
            }

            res(body)
        });
    })

现在,您正在“拒绝”每个回复。

答案 1 :(得分:0)

我不确定“ request”,但是使用“ request-promise-native”可以简化一些事情。

const stocks = require('./stocks.json');
const request = require('request-promise-native');

const parseStocks = (stocks)=>Promise.all(stocks.map(requestQuote));

const requestQuote = ({stockopediaTicker})=>{
    const options = {
        method: 'GET',
        url: `https://www.stockopedia.com/ajax/get_prices/${stockopediaTicker}/`
    };
    return request(options)
}

parseStocks(stocks).then(console.log).catch(console.log)

通常我不建议在答案中更改依赖项,但是在这种情况下,“ request-promise-native”由“ request”文档建议。如果您打算使用Promise,则可能需要切换。通常最好的方法是避免将回调和诺言链结合在一起。

答案 2 :(得分:0)

您的代码使用正确的方法。

  1. 如果确实有错误,您只需要致电rej(err)
  2. 您不应尝试与所有请求共享相同的选项对象(可能会或可能不会引起问题)
  3. 您需要在promises可以使用的更高范围内声明Promise.all(promises)

在解决这些问题后,情况如下:

const stocks = require('./stocks.json')
const request = require("request");

let promises = [];
let stockTickers = stocks.map(x => x.stockopediaTicker);

stockTickers.forEach(ticker => {
    let todaysQuote = new Promise(function (res, rej) {
        let options = {
            method: 'GET',
            url: 'https://www.stockopedia.com/ajax/get_prices/' + ticker + '/'
        };
        request(options, function (error, response, body) {
            if (error) {
                rej(error);
            } else {
                res(body);
            }
        });
    })
    promises.push(todaysQuote)
});

Promise.all(promises)
    .then((results) => {
        console.log(results);
    }).catch(err => console.log(err))

request-promise模块使用起来更加简单,因为它已经包含了一个promise包装器,并且使用.map()来积累您的promise数组可能更容易。

const stocks = require('./stocks.json')
const rp = require("request-promise");

Promise.all(stocks.map(x => {
    let options = {
        method: 'GET',
        url: 'https://www.stockopedia.com/ajax/get_prices/' + x.stockopediaTicker + '/'
    };
    return rp(options);
})).then(results => {
    console.log(results);
}).catch(err => {
    console.log(err);
});