【问题标题】:Is it possible to share a const to scope outside a block or closure是否可以将 const 共享到块或闭包之外的范围
【发布时间】:2018-07-13 07:34:33
【问题描述】:

以这个函数为例

async function foo () {
  const res = await fetchData()
  const out = await processData(res)
  return out
}

想象一下,我注意到 fetchData 很慢,我想使用通用计时器函数/生成器快速分析:

async function foo () {
  for (let time of timer()) {
    const res = await fetchData()
  }
  const out = await processData(res) // error res is undefined
  return out
}

这会破坏代码,因为不再定义 res。我可以在块之前定义let res,或者使用var,但这意味着修改一些临时分析代码的源代码。我想这正是const 的重点是scoping to statements。不过,我还是觉得有办法保持范围,并在一组行前后触发一个事件?

我没有嫁给发电机。闭包可以做同样的工作,但有相同的范围问题。欢迎提供其他语法建议。

如何包装一些任意代码块但保持变量范围?也许是a proxy?类似于 python 的上下文管理器。这可能处于语言限制的边缘?

【问题讨论】:

  • 似乎您可以使用接受回调或承诺并返回结果的分析函数
  • 您已经确定了两种解决方案(使用let 预定义或使用var)。如果您在块内移动 letconst 声明,则将其范围缩小到仅该块。没有办法解决这个问题——这就是语言定义。通过将其包装在一个块中,您缩小了在该块中定义的变量的范围,使用constlet。如果不更改块内的代码,就无法解决这个问题。
  • 请注意,将分析计时器实现为生成器将是一个巨大的错误。由于其可中断控制流的性质,生成器函数会导致巨大的性能损失。如果您不相信我,请尝试对生成器函数与等效的 for 循环进行基准测试。
  • @PatrickRoberts 这只是为了分析,所以它几乎永远不会投入生产。生成器的速度足以满足我的要求。但是我对任何其他语法持开放态度。我没有与生成器、回调或块结婚
  • 我没有看到使用 var 的问题,但我猜肯定有各种分析选项不需要任何代码更改

标签: javascript ecmascript-6 ecmascript-2017


【解决方案1】:

你觉得这样的事情怎么样?

async function timed(p) {
  const start = performance.now();
  const res = await p();
  const end = performance.now();
  console.log('time elapsed', end - start);
  return res;
}

async function foo () {
  const res = await timed(fetchData);
  const out = await processData(res);
  return out
}

【讨论】:

  • 这行不通,因为您在 timed 之前调用了 fetchData,而且我希望它适用于任意数量的行
  • 由于fetchData 是一个承诺,它可能会立即返回。如果要捕获多个,可以将它们包装在异步匿名函数中。但是,您只能获得一个返回值。
  • fetchData() -> fetchData, await p -> await p()
  • 另外,performance.now() 具有微秒分辨率(返回为浮点毫秒值),而 Date.now() 仅具有(不可靠的)毫秒分辨率。
【解决方案2】:

我不知道您所说的“使用通用计时器函数/生成器快速配置 fetchData”是什么意思。我所看到的只是您将语句移到了一个循环中,显然它可能会被执行多次或根本不执行,因此您不能轻易地将一个结果值分配给外部范围 res 变量。

如果您想在某些数据结构上使用循环,是的,只需使用 let res 并从循环中获取最后一个值(或在循环体未运行的情况下获取初始值)。

如果您想分析fetchData 函数,请查看How to measure the execution time of a promise?

【讨论】:

    猜你喜欢
    • 2014-01-12
    • 2022-01-25
    • 1970-01-01
    • 1970-01-01
    • 2011-11-11
    • 2011-06-19
    • 1970-01-01
    • 2010-09-21
    • 1970-01-01
    相关资源
    最近更新 更多