首页 > 解决方案 > 在 Node.js 10.xx 中如何保证所有请求都异步完成,并将请求 url 映射到 promise 响应?

问题描述

我有几个 GET 请求需要发出,并且由于超时限制,它们必须异步运行,我需要保证全部运行。此外,当结果返回时,我需要知道它被引用到哪个 URL。

我设法解决的第一部分,但我无法映射到正确的网址。这是代码:

urls = ['https://example-a.com', 'https://example-b.com', 'https://example-c.com']

Promise.all(promises.map(p => fetch(p.url))).then(function(res){
    var blobPromises = [];

    /* HERE I WOULD LIKE TO KNOW WHICH URL'S REQUEST WAS RETURNED */
    
    for (var j = 0; j < urls.length - 1; j++) {
        blobPromises.push(res[j].text());
    }
    return Promise.all(blobPromises);
}).then(function(body){
    var output = {rawData: body)};
    callback(null, output);
}).catch(callback);

这个映射怎么做?

标签: javascriptnode.jspromisefetch

解决方案


您似乎错误地假设 then 处理程序Promise.all为每个承诺调用一次。相反,它被调用一次(或者如果不是所有的 Promise 都解析),则使用一个包含每个 Promise 的解析的数组(与它们的 Promise 的顺序相同)。

let promises = [Promise.resolve(1), Promise.resolve(2), Promise.resolve(3)];
Promises.all(promises).then(resolveObjects => 
  console.log(resolveObjects)); // [1, 2, 3]

对于您的示例(稍作修改,因为您的代码缺少一些变量和不正确的语句):

urls = ['https://example-a.com', 'https://example-b.com', 'https://example-c.com']

let promises = urls.map(url => fetch(url));

let responses = Promise.all(promises).then(responses => 
    responses.map(respnose => response.text()));

(旁注),异步流依赖(例如https://www.npmjs.com/package/bs-better-stream)将允许您处理承诺数组或承诺数组(或承诺数组的承诺.. .) 更像普通数组。

let responses = new Stream()
  .writePromise(...promises)
  .map(response => response.text());

推荐阅读