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。