js有很多异步处理的解决方案,哪个好那个坏谁也说不清,而 ES
中所包含的async
函数,却是让人感到眼前一亮,找到了解决 JavaScript 对于异步操作的最好操作,完美的可通过 Async
和 Await
轻松的进行扁平化处理。
async/await
从字面意思上很好理解,async
是异步的意思,await有等待的意思,而两者的用法上也是如此。async
用于申明一个function
是异步的,而await
用于等待一个异步方法执行完成。
也就是这样一个过程:
async
表示这是一个 async
函数,而 await
只能在这个函数里面使用。await
表示在这里等待 await
后面的操作执行完毕,再执行下一句代码。await
后面紧跟着的最好是一个耗时的操作或者是一个异步操作(方法)。 async
用于定义一个异步函数,该函数返回一个Promise
。
如果async
函数返回的是一个同步的值,这个值将被包装成一个理解resolve
的Promise
,等同于return Promise.resolve(value)
。
await
用于一个异步操作之前,表示要“等待”这个异步操作的返回值。await
也可以用于一个同步的值。
function getSomething() {
return "something";
}
async function testAsync() {
return Promise.resolve("hello async");
}
async function test() {
const v1 = await getSomething();
const v2 = await testAsync();
console.log(v1, v2);
}
test(); // something hello async
这里就会说明一个问题了,为什么await关键词只能在async函数中用?
await
操作符等的是一个返回的结果,那么如果是同步的情况,那就直接返回了。
那如果是异步的情况呢,异步的情况下,await
会阻塞整一个流程,直到结果返回之后,才会继续下面的代码。
阻塞代码那会很难受,所以await
关键词就只能在async
函数中使用了。
//返回一个同步的值
let sayHi = async function sayHi(){
let hi = await 'hello world';
return hi; //等同于return Promise.resolve(hi);
}
sayHi().then(result=> {
console.log(result);
});
上面这个例子返回是一个同步的值,字符串'hello world'
,sayHi()
是一个async函数,返回值被包装成一个Promise
,可以调用then()
方法获取返回值。
对于一个同步的值,可以使用await
,也可以不使用await
。效果效果是一样的。具体用不用,看情况。
我们都知道promise
并不是只有一种resolve
,还有一种reject
(错误处理)的情况。而await
只会等待一个结果,那么发生错误了该怎么处理呢?
我们可直接在async
函数中抛出一个异常,由于返回的是一个Promise
,因此,这个异常可以调用返回Promise
的catch()
方法捕捉到。
let sayHi = async function sayHi(){
throw new Error('出错了');
}
sayHi().then(result=> {
console.log(result);
}).catch(err=> {
console.log(err.message); //出错了
});
Promise
最大的好处是在异步执行的流程中,把执行代码和处理结果的代码清晰地分离了,但是如果业务场景是这样呢?我们先调起promise1,然后根据返回值,调用promise2,之后再根据这两个Promises得值,调取promise3。代码如下:
const req = () => {
return promise1()
.then(value1 => {
// do something
return promise2(value1)
.then(value2 => {
// do something
return promise3(value1, value2)
})
})
}
再好的解决方案,在项目结构复杂以后总会出现问题,promise
正是如此,代码虽然条理清晰,但是也显得臃肿。
而相同的业务场景,使用async/await
确实十分的爽~
const req = async () => {
const value1 = await promise1()
const value2 = await promise2(value1)
return promise3(value1, value2)
}
学习async/await
还是很有必要的,可能偶尔在什么地方用到,就来了一波骚操作。