Node.js使用request库按顺序逐个请求URL并添加请求间隔的实现问题
问题根因
- 原代码的
for循环为同步执行逻辑,会一次性触发所有请求,最终返回顺序由服务端响应速度决定,无法匹配URL列表的顺序 - 索引变量
i用var声明存在变量提升,所有请求回调触发时读取的都是循环结束后的最终值,因此控制台始终输出最大页码
最小改动适配方案
不需要重构现有核心逻辑,仅需要新增异步控制代码即可实现顺序请求+固定间隔,修改后代码如下:
const request = require('request'); const fs = require('fs'); const prod = fs.readFileSync('prod.txt', "utf8"); const prodid = prod.split("|"); var summary = []; // 把原回调式的request封装成Promise,适配async/await调用 const requestPromise = (url, options) => { return new Promise((resolve, reject) => { request(url, options, (err, res, body) => { if (err) return reject(err); resolve({res, body}); }) }) } // 延迟工具函数,控制请求间隔 const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms)); // 异步主函数实现串行请求 const runFetch = async () => { for (let i = 0; i < prodid.length; i++) { try { const { body } = await requestPromise('https://www.api.example.com/id='+prodid[i], { json: true }); if (body == 'NULL') { console.log("Page " + (i+1) + " out of " + prodid.length + " is NULL!"); } else { summary.push(body.items[0].Name); summary.push(body.items[0].ISOnr); summary.push(body.items[0].GTIN); console.log("Page " + (i+1) + " out of " + prodid.length + " is done!"); fs.appendFileSync('data.txt',JSON.stringify(summary)); } } catch (err) { console.log(err); } // 非最后一个请求则等待1000ms再发起下一个 if (i !== prodid.length -1) { await sleep(1000); } } } runFetch();
方案说明
- 原有请求处理、数据写入的业务代码几乎完全保留,无需大范围重构
- 自动按
prodid列表的顺序逐个发起请求,上一个请求处理完成后才会触发下一个 - 每两个请求之间默认间隔1000ms,可按需修改
sleep的传值调整间隔时长 - 索引
i改用块级作用域的let声明,进度输出完全匹配实际请求顺序
内容的提问来源于stack exchange,提问作者Carje
相关产品推荐
相关产品推荐

