async/await 比 yield 好在哪里?
发布于 15 天前 作者 alsotang 1970 次浏览 来自 问答

我一直很奇怪的一个问题是,async/await 比 yield 好在哪里?除了前者是标准,而后者比较 hack 之外。

在我眼中,前者作为标准,应该是会来到的。而后者作为一种 hack 的方式,虽然不是 generator 的本意,但它的实现既不会发生大的更改,也不会 deprecated。那么 yield 的用法就可以一直用下去,不用担心后续兼容的问题。

就功能来说,我觉得 await 只是 yield 的子集。yield 可以接收数组来并发,也可以接收 object 来并发。而 await 貌似只能一次执行一个 promise 吧?

就使用习惯的发展来看,大家在用 await 的过程中,由于 await 是一个语言上的实现,所以只能按js设计者的意思工作,而去看看 co 的实现,会发现 yield 只是起了中介的作用,你可以让 yield 接受各种参数,只要说得过去。这也是为什么 yield 能把 promise 和 chunk 一视同仁的原因。

这么说起来,我感觉 yield 是比 await 优越的。

46 回复

这个问题目前也困扰着我,目前我自己只实践到Promise为止 感觉规范维护者倾向于认为async/await是最终的异步解决方案,所以大家在思想上更容易靠近政治正确? 中央已经讨论决定了就是你了,是不是有种钦定的感觉?

来自酷炫的 CNodeMD

官方标配总会更得人心的,特别是对于广大程序员,yield和await对于他们来说都是黑盒,肯定会优先选择语言级别支持的特性,换位思考下呢😊

来自酷炫的 CNodeMD

yield 不是语言规范?

不管yield是否优越,但总归是上不了台面的

@leizongmin 就像老婆和小三的地位

来自酷炫的 CNodeMD

语意,作为语法来讲,怎么说贴切最重要了。 yield 对大多数人来说,理解起来是晦涩的,这点就完败了。

而且 async/awiat 的功能还一再阉割,虽然这是标准也实在是…

我觉得不过就是一个是亲生的一个是领养的,就这么简单

async/await is a standard

语义上更规范,其它我也不知道有什么好的。

  1. await 可不是只能一次执行一个 promise await Promise.all([getFoo(), getBar()]);

  2. generator 得用 co/执行器 来执行吧 新人菜逼,轻喷

目前看2者是一样的东西,都是generator,详见 https://cnodejs.org/topic/575bbf22e5fa62531af6e1a8

await 规定只能使用在promise真的好蛋疼,promise本身可读性就差,还得再包装一次

语义才是重点,至于promise,原生的我觉得很好理解吧 自豪地采用 CNodeJS ionic

@i5ting 人真高手都上升到语言的高度来理解的,你呀,非得把那层皮给扒拉下来,你让人家装会逼成么?

语义,语义,语义,重要的事情说三遍,懂了么?

一年一个标准,我是非常,非常,非常看好这样的语言的,重要的事情说三遍,三个非常,就如我看好C++一样,这种标准委员会规范出来的语言那都是集各编程语言之精华的,那都是真真切切要解决程序员的疾苦的。

@coordcn 我错了,你说的对

我觉得大家都在说什么亲生的小三的,什么生成器本来不是这样设计用的,有那么复杂吗?难道现实世界中,你不能拿扳手来敲钉子么? 我家里的窗户装修的时候没弄好,防盗网和墙壁之间有很大的缝隙,夏天蚊子就进来了,我就是拿防撞胶裁剪合适了,塞到缝隙里的,为了压实,最后最趁手的工具居然是衣架!请问完成这些工作,有那样是所谓专业的工具? 还有刚刚看的帖子,elem这个新语言,作者鼓吹他的语言多纯,知乎就有吐槽。所以可见,世界并不是人类想象的那样运行的,即使是人类自己创造的工具。

分享一个链接 http://rossboucher.com/await.

  1. 为了干掉回调地狱,出了个 promise
  2. 但 promise 也不是万金油,then().then().then().,这种代码写多了,代码量也没减多少,也想吐
  3. 为了解决 promise 的坑,为了语义,开发体验,最佳实践吧,出了 async/await,代码量确实减少了很多
  4. Node 还是单线程

@fundon Node还是单线程?去看看Child Processes

@huangyanxiong01 await 仍然是单线程!

@fundon 不阻塞就好了,管它几线程

虽然都处理异步编程的问题,但这些东西并不是完全相互替代的关系 calback => promise => yield (async/await)还有RxJS,因为一段程序不止处理返回值与传参接口,还需要处理side effect,这就像类设计要getter,setter,而不直接用属性赋值。所以会有不少情况一个callback和一个promise比async/await实用的情况,或者说在一些程序里,async/await并不是关键的程序结构,而是一种语法糖而已,真正的核心仍然是一个Promise序列。

通用,好用就好

@huangyanxiong01 可能你跟 @fundon 对于多线程的理解不一样。我指的是看这个 await 问题的角度不一样。

child_process 那已经是新开一个进程了。在当前进程中,js无论如何都是单线程的,libuv那层面的多线程 file io 不能算进来。

@flamingtop 呃。。。跳出题目来说的话,async await 和 yield 可以看成语法糖没错。

受到这个启发,写了一个模块,yield 并发执行 https://github.com/classfellow/pyield

@classfellow yield 后面直接跟一个 promise 数组的话,这些 promise 都会并发执行啊。你试试看。

@alsotang 感觉yield 形式上简单,照着写即可,甚至不必了解清楚promise 。pyield 有意回避更多的概念实现多并发,嘿嘿嘿。对与我这种C++出身的人,更喜欢yield

@alsotang async/await 相对于 Generator,1)语义上更容易理解一些 2)async/await 更规范一些,后面只能接 Promise,并且返回的也是 Promise,而 Promise 对开发者也是隐形的。而 Generator 只是迭代器的一个子类型,设计时并不是拿来解决异步问题,只是我们发现可以用来解决问题。Generator 执行时需要借助第三方执行器,如:co,最后支持哪些功能需要依赖第三方执行器包装了哪些东西。co 里使用 Promise(用其他也是可以的),抹平了 yield 和 yield * 的差异,yield 后面是数组的话自动加 Promise.all 来并行执行。

简单点说,js出身的对异步比较熟悉的都喜欢yield,别的语言转过来不熟悉异步的都喜欢async/await。。。哈哈,猜测一下,反正我是菜鸡,喜欢async/await

适合自己就行啦。开发一个网站有人喜欢java,有人喜欢.Net。萝卜青菜而已。

只要任何东西都可以变成一个Promise之后,await的功能不会比yield弱的。 https://github.com/JacksonTian/tinywork (注意名字) 要理解async/await还得先理解Promise的意图,Promise带有延迟求值的意思(更多细节参见:http://alinode.aliyun.com/blog/5 ),async/await就是为之在语义上的准备。 Generator目前在co的帮助下能实现async/await的功能,但async/await是不需要借助外部工具即可用的。

@welefen aa后面只能跟promise,yield可以跟数组或者对象很方便,aa还得用Promise.all或者bb转一下,略麻烦 From Noder

这么巧最近经常看到有新人问「Monad 跟 Continuation是等价的,那为什么还要 Monad?」 ……我只想表示,中断也是事件

然后,我们其实不需要 this —— by Douglas Crockford

我个人还是比较喜欢yield 因为 object 和 array 并发很方便,而async实现并发后在手动把并发后的内容整合到object中,反而代码要冗余很多。。async的优点是原生语法,语意更好,但我觉得效率上yield这样的hack也并不会逊色很多。。。 可能重要的缺点是async这种对于新人来说比较容易理解,而yield被co包装后不太容易理解吧 所以,我觉得对于老司机来说,yield array 和 yield {} 要比 async promise… 来的更方便吧。。。

可能我又要挨骂了。。。。

async await 自动co, 语义更清晰… yield 程序员自己可以控制next的时刻, 更灵活

楼上好几个人说了generator本意不是这样用,但实际上generator究竟怎样用才是适当根本没人提过

@welefen 而 Generator 只是迭代器的一个子类型,设计时并不是拿来解决异步问题 真是一言惊醒梦中人,按照这么说generator的设计初衷应该就是用来做循环迭代之类的工作,因为它本质上市一个迭代器?

@youth7 好像是个迭代器诶,做延迟计算的。

@alsotang 跑个题,你把首页广告拿下来了,这网站怎么挣钱啊?

@alsotang 没,我只是好奇,你积分第一应该是这里老大,前两天看到网站还有广告,后来看到没有了,所以问问。这个系统不能发私信,所以用了这个帖子。

拿 async/await 做對比就真的有點 naive 了,當你們嘗試在前端中使用 async/await 后,就會知道由 TJ 創造的 Generator 另類用法的侷限性是多麼嚴重。至於 Generator 的真正意義?直接傳送門吧 https://zhuanlan.zhihu.com/p/20794401

可参考Kyle Simpson的博文。 generators 强在代码流程控制;async functions 侧重函数值传递。

再参考Daniel Earwicker的评论

async/await is nothing more or less than the way to consume and return promises. As that’s what a huge amount of JS code does, hence it exists.

If you’re consuming and returning promises, use async/await and move on.

If you’re doing something else besides consuming/returning promises, then sure, async/await is not for you, and this includes building your own for coroutine system with whatever unique quirks you want to bake in.

回到顶部