Как разрешить несколько запросов GET в forEach с помощью NodeJS - PullRequest
0 голосов
/ 14 июня 2019

У меня есть несколько биржевых тикеров в файле 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 голосов
/ 14 июня 2019

Я не уверен насчет «запроса», но используя «запрос-обещание-нативный», вы можете упростить некоторые вещи, подобные этой.

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-обещание-нативный».Если вы планируете использовать обещания, вы можете переключиться.Обычно рекомендуется избегать объединения обратных вызовов и цепочек обещаний.

0 голосов
/ 15 июня 2019

Вы были на правильном пути с вашим кодом.

  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))

Модуль запроса-обещания проще в использовании, поскольку в него уже включена оболочка обещания, и, вероятно, проще использовать .map() для накопления массива обещаний.

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);
});
0 голосов
/ 14 июня 2019

Вы должны проверить, есть ли ошибка, и только rej, если есть ошибка:

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

            res(body)
        });
    })

Прямо сейчас вы «отклоняете» каждый ответ.

...