- 原文地址:Javascript - Generator-Yield/Next & Async-Await
- 原文做者:Deepak Gupta
- 译文出自:掘金翻译计划
- 本文永久连接:github.com/xitu/gold-m…
- 译者:iceytea
- 校对者:huimingwu, zsky
Generator (ES6)javascript
generator 函数是一个能够根据用户需求,在不一样的时间间隔返回多个值,并能管理其内部状态的函数。若是一个函数使用了 function* 语法,那么它就变成了一个 generator 函数。前端
它们与正常函数不一样,正常函数在单次执行中完成运行,而 generator 函数能够被暂停和恢复。它们确实会运行完成,但触发器在咱们手中。它们使得对异步函数能有更好的执行控制,但这并不意味着它们不能用做同步函数。java
注意:执行 generator 函数时,会返回一个新的 Generator 对象。node
generator 的暂停和恢复是使用 yield
和 next
完成的。让咱们来看看它们是什么,以及它们能作什么。android
yield
关键字暂停 generator 函数的执行,而且yield
关键字后面的表达式的值将返回给 generator 的调用者。它能够被理解为基于 generator 版本的return
关键字。ios
yield
关键字实际上返回一个具备 value
和 done
两个属性的 IteratorResult
对象。(若是你不了解什么是 iterators 和 iterables,点击这里阅读)。git
一旦暂停
yield
表达式,generator 的代码执行将保持暂停状态,直到调用 generator 的next()
方法为止。每次调用 generator 的next()
方法时,generator 都会恢复执行并返回 iterator 结果。es6
嗯……理论先到这里,让咱们看一个例子:github
function* UUIDGenerator() {
let d, r;
while(true) {
yield 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
r = (new Date().getTime() + Math.random()*16)%16 | 0;
d = Math.floor(d/16);
return (c=='x' ? r : (r&0x3|0x8)).toString(16);
});
}
};
复制代码
UUIDGenerator 是一个 generator 函数,它使用当前时间和随机数计算 UUID ,并在每次执行时返回一个新的 UUID 。redux
要运行上面的函数,咱们须要建立一个能够调用 next()
的 generator 对象:
const UUID = UUIDGenerator();
// UUID is our generator object
UUID.next()
// return {value: 'e35834ae-8694-4e16-8352-6d2368b3ccbf', done: false}
复制代码
每次 UUID.next() 返回值的 value 值是新的 UUID ,done 值将始终为 false ,由于咱们处于一个无限循环中。
注意:咱们在无限循环上暂停,这是一种很酷的方式。在 generator 函数中的任何“中止点”处,不只能够为外部函数生成值,还能够从外部接收值。
有许多 generator 的实现,而且不少库都在大量使用。好比说 co、koa 和 redux-saga。
依照惯例,当一个异步操做返回由 Promise
处理的数据时,回调会被传递并调用。
Async/Await 是一种特殊的语法,以更温馨的方式使用 Promise,这种方式很是容易理解和使用。
Async 关键字用于定义异步函数 ,该函数返回一个 AsyncFunction 对象。
Await 关键字用于暂停异步函数执行,直到 Promise
被解决(resolved 或者 rejected),并在完成后继续执行 async
函数。恢复时,await 表达式的值是已执行的 Promise 的值。
关键点:
- Await 只能在异步函数中使用。
- 具备 async 关键字的函数将始终返回 promise。
- 在相同函数下的多个 await 语句将始终按顺序运行。
- 若是 promise 正常被 resolve,则
await
会返回promise
结果。可是若是被 reject,它就会抛出错误,就像在那行有throw
语句同样。- 异步函数不能同时等待多个 promise。
- 若是在 await 以后使用 await 屡次,而且后一条语句不依赖于前一条语句,则可能会出现性能问题。
到目前为止一切顺利,如今让咱们看一个简单的例子:
async function asyncFunction() {
const promise = new Promise((resolve, reject) => {
setTimeout(() => resolve("i am resolved!"), 1000)
});
const result = await promise;
// wait till the promise resolves (*)
console.log(result); // "i am resolved!"
}
asyncFunction();
复制代码
在 await promise
这一行,asyncFunction
执行“暂停”,并在 promise 被解决后回复,result
(第 95 行的 const result
)变成它的结果。上面的代码在一秒钟后展现 “i am resolved!
”。
next
方法),而 Async-await 按照 await 接着 await 的顺序依序执行。若是您想要添加到个人电子邮件列表中,请考虑 在此处输入您的电子邮件,并在 medium 上关注我以阅读更多有关 javascript 的文章,并在 github 上查看个人疯狂代码。若是有什么不清楚的,或者你想指出什么,请在下面评论。
你可能也喜欢个人其余文章:
若是你喜欢这篇文章,请鼓掌。提示:你能够拍 50 次!此外,欢迎推荐和分享,以帮助其余人找到它!
谢谢!
若是发现译文存在错误或其余须要改进的地方,欢迎到 掘金翻译计划 对译文进行修改并 PR,也可得到相应奖励积分。文章开头的 本文永久连接 即为本文在 GitHub 上的 MarkDown 连接。
掘金翻译计划 是一个翻译优质互联网技术文章的社区,文章来源为 掘金 上的英文分享文章。内容覆盖 Android、iOS、前端、后端、区块链、产品、设计、人工智能等领域,想要查看更多优质译文请持续关注 掘金翻译计划、官方微博、知乎专栏。