每个API请求之间的延迟

时间:2020-08-23 09:16:06

标签: javascript node.js

我想使用API​​来获取价格数据。我需要发送100个请求,每个请求之间都需要延迟。不会得到429错误。我如何以实际的方式实现这一目标。我正在使用NodeJS。

/* Get Sparkline data from CoinGecko*/
function getSparklineData (marketDataUSD) {
    return new Promise((resolve, reject) => {

        //Get sparkline for every id in marketDataUSD
        marketDataUSD.forEach((coin) => {
            // Get API market data from CoinGecko
            let reqSparklineDataUSD  =  unirest("GET", "https://api.coingecko.com/api/v3/coins/"+coin.id+"/market_chart?vs_currency=usd&days=24hours");

            //Wait for response from CoinGecko
            reqSparklineDataUSD.end((resSparklineDataUSD) => {
                //Checking for request errors
                if (!resSparklineDataUSD.error) {
                    console.log(coin.id)
                    // console.log(resSparklineDataUSD.body.prices)
                    resolve(resSparklineDataUSD.body)
                } else {
                    console.log("Something went wrong:\n"+ resSparklineDataUSD.error)
                    reject()
                }
            });
        });
    })
}

2 个答案:

答案 0 :(得分:2)

您还没有说过要如何存储结果,但是这是一种方法,该方法适用于将它们存储在数组中的任何最新版本的Node.js。

首先,让我们执行一个函数,该函数返回一个诺言,该诺言会请求单个硬币。显然,unirest函数的返回值是一个承诺,因此:

async function getCoinGecko(coinId) {
    const reqSparklineDataUSD = await unirest("GET", "https://api.coingecko.com/api/v3/coins/"+coinId+"/market_chart?vs_currency=usd&days=24hours");
    return resSparklineDataUSD.body;
}

让我们给自己一个基于承诺的setTimeout

// A promise-enabled delay function
function delay(ms, value) {
    return new Promise(resolve => setTimeout(resolve, ms, value));
}

现在我们可以使用async函数,该函数返回结果数组的承诺(例如):

async function getSparklineData(marketDataUSD) {
    const results = [];
    let first = true;
    for (const {id} of marketDataUSD) {
        if (first) {
            // Don't delay on the first loop
            first = false;
        } else {
            // Delay on the second loop onward
            await delay(lengthOfDelayInMS);
        }
        // Get this result
        results.push(await getCoinGecko(id));
    }
    return results;
}

或者这是最后一个函数的版本,该函数返回对Map硬币ID =>数据的承诺:

// An async function returns a promise and can use `await` to wait for promises
async function getSparklineData(marketDataUSD) {
    const results = nw Map();
    let first = true;
    for (const {id} of marketDataUSD) {
        if (first) {
            // Don't delay on the first loop
            first = false;
        } else {
            // Delay on the second loop onward
            await delay(lengthOfDelayInMS);
        }
        // Get this result
        results.set(id, await getCoinGecko(id));
    }
    return results;
}

答案 1 :(得分:2)

unirest请求对象是Promise,因此您应该使用该对象而不是使用new Promise创建Promise。然后使用await对请求进行排序:

function async getSparklineData (marketDataUSD) {
    let results = [];
    for (let coin of marketDataUSD) {
        let reqSparklineDataUSD = await unirest.get("https://api.coingecko.com/api/v3/coins/"+coin.id+"/market_chart?vs_currency=usd&days=24hours");
        console.log(coin.id):
        results.push(resSparklineDataUSD.body);
    }
    return results;
}

呼叫者可能捕获任何错误:

getSparklineData(marketDataUSD)
    .then(results => process(results))
    .catch(err => console.log("an error occurred", err));