async、await、Promise 都是ES6新增的特性,三者之间又有一层微妙的关系。
Promise
Promise是一個表示异步运算的最终失败或者成功的结果。
Promise有三种状态:进行中(pending)、已完成(fulfilled)、已失败(rejected),且状态一旦从pending更改成fulfilled或者rejected后,其状态不会再改变。
定义Promise的时候,可以根据使用场景,分别使用resolve或者reject回调函数更改Promise状态,并输出相关信息到then或者catch异步操作中。
let p = new Promise( ( resolve, reject ) => {
resolve('success');
} );
p.then( res => {
console.log(res) // => 'success'
}).catch( err =>{
conosle.log(err);
})
async
首先从单词的字面上解释,async的意识是“异步。
在函数前添加关键字async声明该函数为异步函数,具体用法如下。
async function p() {
return 'success';
}
console.log( p() );//Promise
p().then( res => {
console.log( res );// => 'success'
} );
async异步函数内,return将返回一个Promise.resolve(),然后进入then操作。而throw将返回一个Promise.reject(),然后进入catch操作。
综合上面的,async异步函数可以更优雅的书写封装后的Promise函数。
//a,b效果一样 b写法更为简洁
let a = function (val) {
return new Promise((resolve, reject) => {
if (val >= 0) {
resolve('success');
} else {
reject('failed');
}
});
};
let b = async function (val) {
if (val >= 0) {
return 'success';
} else {
throw 'failed';
}
};
a(1).then((res) => {
console.log('a', 1, res); // => 'a' 1 'success'
});
a(-1).catch((err) => {
console.log('a', -1, err); // => 'a' -1 'failed'
});
b(1).then((res) => {
console.log('b', 1, res); // => 'b' 1 'success'
} );
b(-1).catch((err) => {
console.log('b', -1, err); // => 'b' -1 'failed'
});
await
从单词字面上理解,await即为“等待”。之前提到过async异步函数返回的值会封装成一个Promise,然后await关键字的作用就是将Promise的结果Resolve。需要注意使用await的时候注意如果有reject回调,需要catch操作接收。
const a = function (val) {
return new Promise((resolve, reject) => {
if (val >= 0) {
resolve(val + 2);
} else {
reject(val - 2);
}
});
};
const b = async function (val) {
val = await a(val); // => 3
val = val - 2; // => 1
console.log(val); // => 1
return val;
};
b(1).catch(err=>{
console.log(err);
});```