如何在 JavaScript 中执行同步 HTTP 请求

问题描述 投票:0回答:2

我需要在node.js程序中执行未知数量的http请求,并且需要同步发生。只有当收到响应时,才会执行下一个请求。我如何在 JS 中实现它?

我用requset包同步尝试了:

function HttpHandler(url){

  request(url, function (error, response, body) {
     ...
  })

}

HttpHandler("address-1")
HttpHandler("address-2")
...
HttpHandler("address-100")

并与请求-承诺异步:

async function HttpHandler(url){

  const res = await request(url)
  ...

}

HttpHandler("address-1")
HttpHandler("address-2")
...
HttpHandler("address-100")

它们都不起作用。正如我所说,我可以通过程序收到未知数量的 http 请求,这取决于最终用户。

有什么想法可以处理这个问题吗?

javascript node.js http asynchronous async-await
2个回答
4
投票

使用

got()
库,而不是
request()
库,因为
request()
库已被弃用并且不支持承诺。然后,您可以使用
async/await
for
循环对您的呼叫进行一个接一个的排序。

const got = require('got');
let urls = [...];    // some array of urls

async function processUrls(list) {
    for (let url of urls) {
        await got(url);
    }
}

processUrls(urls).then(() => {
    console.log("all done");
}).catch(err => {
    console.log(err);
});

您正在声明某种动态 URL 列表,但不会显示其工作原理,因此您必须自己弄清楚这部分逻辑。我很乐意展示如何解决该部分,但您还没有给我们任何想法应该如何工作。


如果您想要一个可以定期添加项目的队列,您可以执行以下操作:

class sequencedQueue {
    // fn is a function to call on each item in the queue
    // if its asynchronous, it should return a promise
    constructor(fn) {
        this.queue = [];
        this.processing = false;
        this.fn = fn;
    }
    add(...items) {
        this.queue.push(...items);
        return this.run();
    }
    async run() {
        // if not already processing, start processing
        // because of await, this is not a blocking while loop
        while (!this.processing && this.queue.length) {
            try {
                this.processing = true;
                await this.fn(this.queue.shift());
            } catch (e) {
                // need to decide what to do upon error
                // this is currently coded to just log the error and
                // keep processing.  To end processing, throw an error here.
                console.log(e);
            } finally {
                this.processing = false;
            }
        }
    }
}

0
投票

这可以使用我在 2023 年编写的库来实现,sync-request-curl:

该库包含原始 sync-request 中功能的子集,但利用 node-libcurl 在 NodeJS 中获得更好的性能。

这是 GET 请求的基本用例:

// import request from 'sync-request-curl';
const request = require('sync-request-curl');
const response = request('GET', 'https://ipinfo.io/json');
console.log('Status Code:', response.statusCode);
console.log('body:', response.body.toString());

将此应用到您的示例中,它将简单地是:

const request = require('sync-request-curl');

function HttpHandler(url) {
  const response = request('GET', url);
  if (response.statusCode === 200) {
    // assuming your response body is JSON
    return JSON.parse(response.body.toString());
  } else {
    // handle error
  }
}


HttpHandler("address-1")
HttpHandler("address-2")
...
HttpHandler("address-100")

希望这有帮助:)。

© www.soinside.com 2019 - 2024. All rights reserved.