您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

Node.js尾部调用优化:可能吗?

Node.js尾部调用优化:可能吗?

这里有两个相当不同的问题:

: 。它做了一段时间了,一个或另一个,但是在撰写本文时(2017年11月),它不再存在,因为它使用的底层V8JavaScript引擎不再支持TCO。。

细节:

尾呼叫优化(TCO)是ES2015(“ES6”)规范的必需部分。因此,直接支持它不是NodeJS,而是NodeJS使用的V8 JavaScript引擎需要支持的东西。

从Node8.x开始,V8不支持TCO,甚至不支持标记。它可能会在将来的某个时候再次出现。。

节点7.10至少降至6.5.0(我的注释说为6.2,但node.green表示不同意)仅在严格模式下(--harmony在6.6.0及更高--harmony_tailcalls版本中)标记后面支持TCO 。

如果要检查安装,请使用node.green使用的测试(如果使用的是相关版本,请确保使用该标志):

function direct() {
    "use strict";
    return (function f(n){
      if (n <= 0) {
        return  "foo";
      }
      return f(n - 1);
    }(1e6)) === "foo";
}

function mutual() {
    "use strict";
    function f(n){
      if (n <= 0) {
        return  "foo";
      }
      return g(n - 1);
    }
    function g(n){
      if (n <= 0) {
        return  "bar";
      }
      return f(n - 1);
    }
    return f(1e6) === "foo" && f(1e6+1) === "bar";
}

console.log(direct());
console.log(mutual());



$#仅适用于某些版本的Node,尤其不是8.x或(当前)9.x;往上看
$ node --harmony tco.js
真正
真正

这是ES2015的另一件事(“生成功能”),因此也是V8必须实现的东西。它已在Node 6.6.0中的V8版本中完全实现(并且已经有多个版本),并且没有任何标志。

生成函数(使用编写function*和使用的函数yield)能够停止并返回捕获其状态的迭代器,并可以在以后的情况下继续其状态,从而发挥作用。AlexRauschmeyer在这里对它们进行了深入的介绍。

这是一个使用显式生成函数返回的迭代器的示例,但是您通常不会这样做,稍后我们将看到原因:

"use strict";
function* counter(from, to) {
    let n = from;
    do {
        yield n;
    }
    while (++n < to);
}

let it = counter(0, 5);
for (let state = it.next(); !state.done; state = it.next()) {
    console.log(state.value);
}

具有以下输出

0
1个
2
3
4

运作方式如下:

拥有迭代器和状态对象的变量以及调用it.next()和访问doneandvalue属性都是(通常)阻碍我们通常试图做的事情的样板,因此ES2015提供了一条新for-of语句来将其全部删除我们,并给我们每个价值。这是上面用编写的相同代码for-of

"use strict";
function* counter(from, to) {
    let n = from;
    do {
        yield n;
    }
    while (++n < to);
}

for (let v of counter(0, 5)) {
    console.log(v);
}

v对应state.value于我们前面的示例,它完成了for-of所有的it.next()调用done为我们进行检查。

Node 2022/1/1 18:14:48 有464人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶