如何在Node.js的request请求中保存可全局访问的递增变量
问题原因
request属于异步IO操作,对应的回调函数会在所有同步代码(包括你的for循环、循环内的console.log(increment))执行完毕后才会触发,你打印变量的时候请求还没有返回,自然不会执行到increment++的逻辑increment变量声明在for循环内部,每次循环都会重新创建该变量,且未设置初始值,默认是undefined,自增逻辑本身就存在问题
修复方案
你需要把increment变量移到循环外层初始化,同时等待所有异步请求全部执行完成后,再读取该变量的最终值。推荐用Promise改造异步逻辑,示例修改后代码如下:
// 把increment移到循环外层,初始化赋值为0 let increment = 0; // 存储所有请求的Promise实例,用于后续等待所有请求完成 const requestPromises = []; for (let i = 0; i <= queries.startDates.length - 2; i++) { const currentUrl = `https://api.weatherbit.io/v2.0/history/daily?city=${city}&start_date=${queries.startDates[i]}&end_date=${queries.endDates[i]}&key=${historicalApiKey}`; // 将回调式的request包装为Promise const reqPromise = new Promise((resolve, reject) => { request(currentUrl, function(err, response, body) { if (err) { res.render('HistoricalData', { weather: null, error: 'Error, please try again' }); return reject(err); } const weather = JSON.parse(body); if (!weather) { res.render('HistoricalData', { weather: null, error: 'Error, please try again' }); return reject(new Error('返回结果无效')); } const weeklyInfo = structureData(loopThroughDays(weather), organizedTemperaturesMap); increment++; resolve(weeklyInfo); }); }); requestPromises.push(reqPromise); } // 等待所有请求全部完成后,再读取increment的最终值 Promise.all(requestPromises).then(allWeeklyInfo => { console.log(increment); // 后续需要用到increment的逻辑都写在这里 }).catch(err => { console.error('请求执行出错:', err); });
额外注意事项
- for循环的计数变量i不要用默认的var声明,会有变量提升问题,改成let可以保证每次循环拿到的i是当前迭代的独立值
- 如果是新版本Node.js环境,也可以直接使用axios、node-fetch这类原生支持Promise的请求库,不需要自己手动包装回调逻辑
- 不要在循环内部同步读取increment的值,所有依赖该变量最终结果的逻辑,都要放在
Promise.all的回调里执行
内容的提问来源于stack exchange,提问作者tavi
相关产品推荐
相关产品推荐

