上两篇分别说了
和
- Promise
,基础已经打好,现在可以开始讲
- Generator
了。
- async await
是 ES7 的议案,TypeScript 在 1.7 版本开始支持
- async await
编译到 ES6,并在 2.1 版本支持编译到 ES5 和 ES3,算是全面支持了。
- async await
和 C# 里的十分相似,看个例子:
- function delay() : Promise < void > {
- return new Promise < void > ((resolve, reject) = >{
- setTimeout(() = >resolve(), 2000)
- });
- }
- async
- function run() {
- console.info('start');
- await delay();
- console.info('finish');
- }
- run();
- console.info('run');
上面代码执行的结果是执行完
后立即返回一个
- run()
,遇到
- Promise
跳出函数,继续往下走,所以先输出
- await
,再紧接着输出
- start
,过了 2 秒后再输出
- run
。 可以看到
- finish
函数,function 前面多了个
- run
(如果是 class 里的方法,则是在函数名前),delay() 前面多了个
- async
,表示的意思很明显,就是在两者之间等待 2 秒。
- await
函数返回的也是一个
- run
对象,后面可以接
- Promise
来做后续操作。
- then
必须要在
- await
块中,await 的对象可以是
- async
对象也可以不是,不是的话会自动转为已经 resolved 的 Promise 对象。 另外,
- Promise
在代码块中是按顺序执行的,前面 wait 完后再会走下一步,如果需要并行执行,可以和
- await
一样,用
- Promise
或
- Promise.all
来达到目的。
- Promise.race
- async
- function run1() {
- await delay();
- console.info('run1');
- }
- async
- function run2() {
- await delay();
- console.info('run2');
- }
- async
- function run3() {
- await delay();
- console.info('run3');
- }
- Promise.all([run1(), run2(), run3()]);
上面代码会在两秒后几乎同时输出 run1, run2, run3。
一个 async 函数中可以有 N 个 await,async 函数返回的 Promise 则是由函数里所有 await 一起决定,只有所有 await 的状态都 resolved 之后,async 函数才算真正完成,返回的 Promise 的状态也变为 resolved。
当然如果中间 return 了或者出了异常还是会中断的。
- async
- function run() {
- console.info('start');
- await delay();
- console.info('time 1');
- await delay();
- console.info('time 2');
- return;
- //下面当然就不会执行了
- await delay();
- console.info('time 3');
- }
的状态在 time 2 输出后 return 就转为
- run
了。 当这里出异常时,async 函数会中断并把异常返回到
- resolved
里的
- Promise
函数。
- reject
- async
- function run() {
- await Promise.reject('error'); // 这里出异常
- console.info('continue'); // 不会执行到这里
- await delay();
- }
之前有提到
的异常可以在后面用
- Promise
来捕获,
- catch
也一样。 向上面的例子,可能有需要把整个函数即使出异常也要执行完,就可以这样做:
- async await
- async
- function run() {
- await Promise.reject('error').
- catch(e = >console.info(e));
- console.info('continue'); // 继续往下执行
- await delay();
- }
- let g = run(); //这里的g也是成功的,因为异常已经被处理掉
如果是多个异常需要处理,可以用
- try...catch
- async
- function run() {
- try {
- await Promise.reject('error1');
- await Promise.reject('error2');
- } catch(e) {
- console.info(e);
- }
- console.info('continue'); // 继续往下执行
- await delay();
- }
前篇有说过
其实是
- async await
的语法糖。
- Generator
换成
- *
,
- async
换成
- yield
之外,最主要是
- await
内置了执行器,不用像
- async await
用那样
- Generator
一直往下执行。 其实也就是
- next()
内部做了 co 模块做的事。
- async await
先来看看 async await 在 TypeScript 翻译后的结果:
- async
- function run() {
- await delay();
- console.info('run');
- }
- //翻译成
- function run() {
- return __awaiter(this, void 0, void 0,
- function * () {
- yield delay();
- console.info('run');
- });
- }
可以注意到其实还是用
包了一个
- __await()
函数,
- Generator
的实现其实和上篇的 co 模块的实现基本一致:
- __await()
- var __awaiter = (this && this.__awaiter) ||
- function(thisArg, _arguments, P, generator) {
- return new(P || (P = Promise))(function(resolve, reject) {
- function fulfilled(value) { // 也是fulfilled,resolved的别名
- try {
- step(generator.next(value)); // 关键还是这个step,里面递归调用fulfilled
- } catch (e) {
- reject(e);
- }
- }
- function rejected(value) {
- try {
- step(generator["throw"](value));
- } catch (e) {
- reject(e);
- }
- }
- function step(result) {
- result.done ? resolve(result.value) : new P(function(resolve) { //P是Promise的类型别名
- resolve(result.value);
- }).then(fulfilled, rejected); // 没有done的话继续fulfilled
- }
- step((generator = generator.apply(thisArg, _arguments)).next());
- });
- };
来源: http://www.cnblogs.com/brookshi/p/6426726.html