传递给异步函数的参数范围

Scope of parameter passed to async function

{
  const data = new Uint8Array([0x01]);
  await input_writer.write(data);
}

在上面的示例中,'data' 被传递给异步操作,然后立即进行范围外处理。底层内存会发生什么?在异步函数完成之前它是否一直存在?

起初我以为data只是代码块末尾的垃圾回收器,但似乎JavaScript引擎比我想象的更聪明。

的确,当执行这段代码时:

class Test {}

(async function() {
  const data = new Test;
  await write(data);
  console.log('never');

  function write(data) {
    return new Promise(() => {});
  }
})();

然后使用“内存”选项卡拍摄内存快照,搜索时没有Test显示。

但是,如果您尝试此代码段并拍摄新快照,则会显示该实例,因为 write 的此实现将 data 传递给 setTimeout,后者保留对 [= 的引用12=] 特定时间:

class Test {}

(async function() {
  const data = new Test;
  await write(data);
  console.log('in a long time');

  function write(data) {
    return new Promise(resolve => setTimeout(() => resolve(data), 999999999));
  }
})();

注意:您必须将其粘贴到您的控制台才能在内存快照中看到它。

总而言之,如果 write 没有副作用保存对 data 的引用,JavaScript 引擎(至少是 chromium)似乎足够聪明来确定data 即使在代码块结束之前也不会再被使用,这有助于尽快清除内存。