如何使用 Promise.all 循环遍历 API 调用列表,同时在每次调用之间也有延迟?

时间:2021-01-23 03:51:12

标签: javascript asynchronous promise

我阅读了有关使用 axios/fetch/requests 从 url 列表(api 调用)检索数据的各种不同问题。我意识到以前也有人问过类似的问题。我有一些几乎可以工作的代码,但我不知道如何在调用之间延迟。我的超时没有按照我想要的方式工作。我希望它在两次调用之间等待 3000 毫秒。

const request = require('request');

var requestAsync = function(url) {
    return new Promise((resolve, reject) => setTimeout(() => {
        var req = request(url, (err, response, body) => {
            if (err) return reject(err, response, body);
            resolve(JSON.parse(body));
        });
    },3000))  ;
};

const urls = [
    'https://jsonplaceholder.typicode.com/posts',
    'https://jsonplaceholder.typicode.com/albums',
    'https://jsonplaceholder.typicode.com/users'
];


var fetchURLdata = async function() {
  
    try {
        var data = await Promise.all(urls.map(requestAsync));
        console.log(data)
    } catch (err) {
        console.error(err);
    }
    console.log(data);
}

fetchURLdata();

2 个答案:

答案 0 :(得分:1)

如果您希望以串行方式而不是并行方式发出请求,则使用 for 循环会更有意义:

const requestAsync = (url) => new Promise((resolve, reject) => {
    request(url, (err, response, body) => {
        if (err) reject(err, response, body);
        else resolve(JSON.parse(body));
    });
});

const delay = ms => new Promise(res => setTimeout(res, ms));

const fetchURLdata = async () => {
    try {
        const data = [];
        for (const url of urls) {
            data.push(await requestAsync(url));
            await delay(3000);
        }
        console.log(data);
    } catch (err) {
        console.error(err);
    }
};

答案 1 :(得分:1)

除了上述答案之外,我想补充一点,Promise.all 正在同时处理您的请求,而不是一次一个。要了解我的意思,请尝试在此处输入控制台日志:

var requestAsync = function(url) {

    // NEW CODE HERE
    console.log("This request is being executed at:", Date.now()) 
    // END NEW CODE

    return new Promise((resolve, reject) => setTimeout(() => {
        var req = request(url, (err, response, body) => {
            if (err) return reject(err, response, body);
            resolve(JSON.parse(body));
        });
    },3000))  ;
};

您应该看到每个请求同时开始。

我同意CertainPerformance 的观点,即您希望将其放入for 循环中以获得您所追求的顺序行为。