ES7(误)引入的async
函数,可以说是Javascript异步编程代码组织方式的又一次升级。使得代码可以通过顺序式的方式来编写异步逻辑。
1. 创建
创建一个async
函数有两种方式:function
声明和构造函数(和生成器类似)
1.1 async function函数声明
使用async function
的声明方式可以创建async
函数
// 函数声明
async function f() {
return 1;
}
// 也可以使用函数表达式
var f = async function() {
return 1;
}
1.2 AsyncFunction构造函数
和Generator
一样,也可以直接获得原型链上的构造函数AsyncFunction(...arguments, expression)
来创建async
函数,其中构造方法最后一个参数为expression
函数方法体,其余参数...arguments
为函数所需参数
var AsyncFunction = Object.getPrototypeOf(async function(){}).constructor;
var f = new AsyncFunction('a', 'return a*10');
// 相当于
async function f(a){
return a*10;
}
个人觉得还是用async function
的方式来创建async
函数,简单而且易于开发和维护
2. 使用
直接进行方法调用就可以执行async
函数,async
函数将返回一个Promise
对象。其中Promise
的决议值有下面三种情况:
- 如果是函数方法体中存在
return
,则返回值将作为决议值- 如果没有
return
,则决议值为undefined
- 如果方法体中出现异常,则决议值为
reject
的异常信息
// 有return值,返回值作为决议值
async function f1() {
return 1;
}
var af = f1();
console.log(af instanceof Promise); // true;
af.then(fulfill => {
console.log(fulfill); // 1
})
// 没有return,决议值为undefined
(async function() {})().then(fulfill=>{
console.log(fulfill); // undefined
})
// 抛出异常,决议值为reject的异常信息
(async function() {
throw new Error('error');
})().then(fulfill=>{
console.log(fulfill); // undefined
}, reject => {
console.log('got the error: ');
console.log(reject);
})
3. await
async
函数中可以使用await
关键字,和Generator
中的yield
关键字类似,可以理解为await
也能起到暂停的作用,但是await
更具有智能性,Generator
我们需要手动触发next
函数来推动Generator
的yield
的不断运行,但是使用await
将自动实现这一过程,不用再人工进行手动触发,且会将await
后表达式自动进行Promise
转换并在Promise
完成决议后,将决议值返回
// 对于生成器函数和yield
function *g() {
let a = yield new Promise(resolve => {
setTimeout(_=>{
resolve(1);
}, 1000);
});
console.log(1); // 1s后输出1
}
var it = g();
it.next().value.then(fulfill => {
it.next(fulfill); // 手动在回调中调用next,推进iterator的执行
});
// 使用async函数和await
async function f() {
let a = await new Promise(resolve => {
setTimeout(_=>{
resolve(1);
}, 1000);
});
console.log(1); // 1s后输出1
}
f();
从代码可以看出
await
关键字会在表达式决议后获得决议值,之后再继续运行代码- 使用
async
函数,将按照同步的方式自动运行我们的代码,我们不用像Generator
手动调用next
或者使用Generator
的runner
函数,相当于Generator
+Promise
+Generator runner
组合
4. 总结
async
函数可以改变我们异步代码的组织习惯,对于未来的异步代码编写,我们很多时候都可以抛弃异步回调函数的做法了
网友评论