node.js 如何在 for 循环中使用局部变量实现承诺感知?



我有一个for-loop,其中包含一些在循环中声明的局部变量n。因此,我预计一旦程序退出循环,n的值就会被销毁。

但是,似乎n的值在 for 循环之外仍然可用。为什么?另外,我应该在什么时候期望n (also the value k if uncommented)的价值被销毁?

const delayHelper = require('./delayExecutor')
async function main() {
let promises = [];
let records = [1, 2, 3, 4];
for(let i = 0; i < records.length; i++) {
let n = 1000 + records[i];
// let k = 123;
promises.push(delayHelper.delayResolve(() => records[i], 1000).then(data => data + n))
}
console.log(await Promise.all(promises));   //print: [ 1002, 1004, 1006, 1008 ]
}
main()
//delayExecutor.js
let delayedResolve = (fun, ms) => {
return new Promise((y, n) => {
setTimeout(() => {
y(fun());
}, ms);
});
};
exports.delayResolve = delayedResolve;

这里有几个概念需要注意。1.关闭范围, 2.块范围

当您访问内部函数定义中的n时,该变量在该内部函数的闭包范围内保持活动状态,直到不再需要它,

使用let声明n将在块作用域(此处for循环(中创建一个新变量,该变量将在相应的迭代中锁定到内部函数。

您可以尝试的另一件事是使用var声明n这将产生不同的结果 -[1005,1006,1007,1008]。这是因为var不是块范围的声明,因此它不会为循环的每次迭代创建新变量。循环结束时n的最终值1004,该值将在逻辑data => data + n

中使用对于您问题的第二部分 - 据我所知,所有变量引用都将在函数结束时清除。由于您的 n 被锁定在内部函数的 Closure 作用域中data => data = n因此一旦执行,n值将被清除。

您是如何发现可以从厕所外访问n的?我执行了您的代码并尝试访问n超大的循环。我得到n 是未定义的错误。这完全是意料之中的。

现在,垃圾回收器决定何时需要对未使用的内存进行垃圾回收。您可以搜索V8 垃圾回收器

有了Promise.all承诺将并行处理,结果将解决(或拒绝(

let delayedResolve = (fun, ms) => {
return new Promise((y, n) => {
setTimeout(() => {
y(fun());
}, ms);
});
};
Promise.all([1, 2, 3, 4].map(async item=>await delayedResolve(()=> item, 1000)+1000+item))
.then(results=>console.log(results));

代码将首先处理每个承诺,然后显示所有结果。 如果你寻找顺序过程,你需要承诺链。

最新更新