promise和async/await都是異步方案,promise是es6的新特性,而async/await是es7新出的特性。
想必大家對promise有所見過,他是一個對象,可以實現鏈式的寫法來實現同步異步操作,一般我們可以這樣寫:
var pro = new promise (function(resolve,reject){
resolve()
})
同時他有三種狀態:pending(進行中),resolved(已完成),rejected(已失敗);如上面代碼所示,resolve里面表示完成后的操作,reject表示失敗夠所要執行的代碼。但同時我們也可以通過簡易的代碼來表示,如:
var somePromise = function(){
return Promise.resolve('bar');
}
當我們第一個promise對象執行完后執行下一個promise時,我們可以通過鏈式寫法:then()...catch()...,then表示上一個promise執行完后執行,如果出現錯誤就會在catch里面顯示:
var newPromise = function(){
return Promise.resolve('foo').then(somePromise).then(function(result){
console.log("111",result);
}).catch(function(err){console.log("err",err)});
}
var somePromise = function(){
return Promise.resolve('bar');
}
newPromise();
then方法的出現可以幫助我們實現閉包的問題,因為他是在promise執行完后執行:
function timeout(ms) {
return new Promise((resolve, reject) => {
setTimeout(resolve, ms, 'done');
});
}
timeout(100).then((value) => {
console.log(value);
});
此外,then()是期望獲得一個函數,如果是非函數形式的就會顯示then(null);
而對於async/await來說是基於promise的,他可以讓我們更加優雅的寫出代碼,而替代then()的寫法,例如:
const f = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
reject(234);
}, 2000);
});
};
const testAsync = async () => {
try {
const t = await f();
console.log(t);
} catch (err) {
console.log(err);
}
};
testAsync();
在上述代碼中,同樣實現了代碼的先后滯留執行問題;需要注意的是await必須寫在async的作用域內;如果promise函數里是reject,那就會在catch里面執行代碼;在上述代碼中,我們是在async里面先執行promisr代碼,然后再執行下面的代碼,所以我們也可以用他來很好的執行for循環的逐一顯示問題。
一段話解釋就是:await后面等待的是一個結果,不僅僅可以等待一個promise對象,也可以是返回值;async函數是返回的是一個promise對象,一般是在async里return返回值,如果沒有返回值,它會返回 Promise.resolve(undefined),但也不會阻塞后面的語句執行;await后面的值可以是async返回的promise,也可以是簡單的function函數,它需要包含在async函數內;並且通過try{}catch{}來解決promise.reject()報錯的問題。
promise和async/await都是實現異步的好方法,雖然現在還有兼容性的問題,但我們可以使用babel來轉換es6和es7。
