Web 技术研究所

我一直坚信着,Web 将会成为未来应用程序的主流

该来的还是得来——Generator

  只靠Promise就已经可以解决回调嵌套过度的问题了,Promise能把原本垂直的代码变平行。但大家还是喜欢把Generator也用上,虽然比较时髦,但我觉得即便用上Generator也不会对回调嵌套过度的问题有多少改善了,反而会让代码的逻辑变得更糟。
  其实我对ES6中Generator的设计很不满意。function*(){}作为一种语法,它却是函数类型的,而且它的返回结果却是一个内置对象。我觉得这些概念都是非常矛盾的。
  与普通的函数相比,Generator最了不起的地方是“函数体可以使用自身的返回值”。我这种说法有点荒诞,但以传统逻辑来看就是如此。传统函数是不可能使用自己的返回值的,因为函数一旦产生返回值就意味着函数执行结束。而Generator却可以这么写
<script>
console.time("test");
function*G(){
  setTimeout(g.next.bind(g),1000);
  yield 0;
  console.timeEnd("test");
};
var g=G();
g.next();
</script>
  先不管这么写有多蛋疼,至少这样的写法是引擎允许的吧?那么如果G是一个传统意义上的函数,而g就是这个函数被调用后的返回值,那么在G的函数体中使用g就是不合逻辑的,有一种外祖母悖论的感觉。无论上面的代码在G的函数体中使用g是直接还是间接的,或者代码这么写
<script>
console.time("test");
function*G(next){
  setTimeout(next,1000);
  yield 0;
  console.timeEnd("test");
};
var g=G(function(){
  g.next();
});
g.next();
</script>
  这样虽然没有直接在G的函数体中使用g,但它确实间接使用了,我觉得也同样不合适。而且,即使用Promise封装起来,也同样是一种间接的引用
<script>
function test(G){
  var g=G();
  doNext();
  function doNext(e){
    var promise=g.next(e).value;
    if(promise)promise.then(function(e){
      doNext(e);
    });
  };
};
console.time("test");
test(function*(){
  yield new Promise(function(resolve){
    setTimeout(resolve,1000);
  });
  console.timeEnd("test");
});
</script>
  虽然这样封装好之后使用并没有问题,但这和前面的代码实际上是同样的逻辑。而且有必要吗?Promise的话,即使没有Generator已经可以解决回调嵌套过渡的问题了
<script>
console.time("test");
new Promise(function(resolve){
  setTimeout(resolve,1000);
}).then(function(){
  console.timeEnd("test");
  return new Promise(function(){
    //TODO
  });
}).then(function(){
  return new Promise(function(){
    //TODO
  });
}) //etc.
</script>
  我觉得Generator不应该被以函数的形式定义到ES中,因为它本来就不是函数嘛!它应该是一种与代码块和函数有相似概念的新语法来定义,而且调用也不该用一个内置对象来承接后续操作。像g.next(e).value这样的写法,感觉就像indexedDB的API一样更像是一个库。而实际上Generator应该是一个超越传统函数的概念,我觉得应该为其添加一套运算符或语句来处理这些后续操作。
  其实我现在说这些也没啥用了,Generator这东西已经基本上没跑了,甚至很多库都已经依赖它实现了,而且Chrome马上也要开始对其默认启用了。现在这样的Generator实现方式我还是勉强能接受的,至少使用起来不会出问题。只是心中有一种“无可奈何花落去,似曾相识燕归来”的感觉。
网名:
54.144.24.*
电子邮箱:
仅用于接收通知
提交 悄悄的告诉你,Ctrl+Enter 可以提交哦
神奇海螺
[查看全部主题]
各类Web技术问题讨论区
发起新主题
本模块采用即时聊天邮件通知的模式
让钛合金F5成为历史吧!
次碳酸钴的技术博客,文章原创,转载请保留原文链接 ^_^