我需要在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 请求,这取决于最终用户。
有什么想法可以处理这个问题吗?
使用
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;
}
}
}
}
这可以使用我在 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")
希望这有帮助:)。