前面聊了promise,如果不懂的话可以翻看一些前面的文章:传送门
着两个关键字一般都是成对出现的,所以本篇聊一下。
async一般用来修饰函数的,其修饰的函数称为变成async函数。而在这个函数中可以使用await关键字。
因此:await必须写在async函数中,但是async函数中可以没有await。
现在看一下async和await两个关键字各有什么神奇的作用呢,下面依次演示。
async首先看一下官网的解释:
async函数是使用async关键字声明的函数。 async函数是AsyncFunction构造函数的实例, 并且其中允许使用await关键字。async和await关键字让我们可以用一种更简洁的方式写出基于Promise的异步行为,而无需刻意地链式调用promise。
现在看一下格式:
async function name([param[, param[, ... param]]]) {
statements
}
name
函数名称。
param
要传递给函数的参数的名称。
statements
包含函数主体的表达式。可以使用await
机制。
async函数的函数体可以被看作是由0个或者多个await表达式分割开来的。从第一行代码直到(并包括)第一个await表达式(如果有的话)都是同步运行的。这样的话,一个不含await表达式的async函数是会同步运行的。然而,如果函数体内有一个await表达式,async函数就一定会异步执行。
返回值
返回值是一个promise
,这个promise要么会通过一个由async函数返回的值被解决,要么会通过一个从async函数中抛出的(或其中没有被捕获到的)异常被拒绝。async函数一定会返回一个promise对象。如果一个async函数的返回值看起来不是promise,那么它将会被隐式地包装在一个promise中.
老规矩演示:
async function test_async(){
// 这里结果就是将return注释取消结果也不会变 默认就是return 一个undefined
//return;
};
test_async();
再来两个例子:
async function test1(){
// 返回任何值会默认异步成功,也会修改为成功状态
return 1;
};
async function test2(){
// 抛出任何值会默认异步失败,也会修改为失败状态
throw 2;
};
test1();
test2();
可以看出如果是返回的就是promise呢?
async function test3(){
return Promise.resolve(3);
};
async function test4(){
return Promise.reject(4);
};
因为async返回的是promise,自然可以跟then等方法,这个就不再具体演示了,可以看前面聊promise中对then等方法的演示。
而async的神奇 *** 作更多的依靠await关键字,所以这里简单演示用法,后面结合await具体聊。
await官网说到:
await *** 作符用于等待一个Promise 对象。它只能在异步函数 async function 中使用。
看一下格式:
[返回值] = await 表达式;
表达式
一个 Promise 对象或者任何要等待的值。
返回值
返回 Promise 对象的处理结果。简单的理解可以是:await表达式之后的代码可以被认为是存在在链式调用的then回调中,多个await表达式都将加入链式调用的then回调中,返回值将作为最后一个then回调的返回值。
如果等待的不是 Promise 对象,则返回该值本身。
补充:
await 表达式会暂停当前 async function 的执行,等待 Promise 处理完成。若 Promise 正常处理(fulfilled),其回调的resolve函数参数作为 await 表达式的值,继续执行 async function。若 Promise 处理异常(rejected),await 表达式会把 Promise 的异常原因抛出。另外,如果 await *** 作符后的表达式的值不是一个 Promise,则返回该值本身。
演示一个:
function test_f1(val) {
return new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve(val)
},1000)
})
}
async function test_1() {
var test_value=test_f1('test_1').then((value)=>{
console.log('test_1----',value)
});
console.log('test1中 调用test_f1的后面');
}
async function test_2() {
var test_value=await test_f1('test_2');
console.log('test2中 调用test_f1的后面');
console.log('test_2----',test_value)
}
虽然可以await可以等待这个封装在promise异步 *** 作结果,而then却不会。
前面又说道如果等待的不是 Promise 对象,则返回该值本身。
如下演示:
function test_f1(val) {
return val;
}
async function test_2() {
var test_value=await test_f1('test_2');
console.log('test_2----',test_value)
}
又有一个神奇问题,上面返回值可以和返回一个成功状态的promise都可以理解为成功状态,但是难道await后面执行的一定都会成功状态吗?
function test_f1(val) {
// 不再重复代码,这里写throw val 显示结果不会变
return Promise.reject(val);
}
async function test_2() {
var test_value=await test_f1('test_2');
console.log('test_2----',test_value)
}
可以看出await无法得到一个错误状态的Promise对象(或throw 错误对象或者数值,而这个就需要通过try–catch才可以得到这个错误值。
function test_f1(val) {
// 不再重复代码,这里写throw val 显示结果不会变
return Promise.reject(val);
}
async function test_2() {
try{
var test_value=await test_f1('test_2');
}catch (error){
console.log('test_2----',error)
}
}
所以:如果一个错误状态的promise对象(或者throw ),那就会抛出异常,需要通过try-catch来捕获。
优点既然是新特性,那么async和await关键字自然尤其优势。promise最牛逼之一可以写出一个链式 *** 作如下:
function test(n) {
return new Promise(resolve => {
setTimeout(() => resolve(n+1));
});
}
function step1(n) {
console.log(`第一步`,n);
return test(n);
}
function step2(n) {
console.log(`第二步`,n);
return test(n);
}
function step3(n) {
console.log(`第三步`,n);
return test(n);
}
如果通过then进行链式调用:
step1(1).then((value=>step2(value))).then((value=>step3(value)))
然后永async和await关键字试一下。
async function test_async(){
var return1=await step1(1);
var return2=await step2(return1);
var return3=await step2(return2);
}
test_async()
是看着会更具舒服一些。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)