Promise
對象是一個代理對象(代理一個值),被代理的值在Promise對象建立時多是未知的。它容許你爲異步操做的成功和失敗分別綁定相應的處理方法(handlers)。 這讓異步方法能夠像同步方法那樣返回值,但並非當即返回最終執行結果,而是一個能表明將來出現的結果的promise對象
若是遇到接口的調用參數依賴於上一個接口的返回值,咱們通常會這麼寫promise。es6
function getApi(params) { return new Promise((resolve) => { // 模擬ajax setTimeout(() => { resolve('api result: ' + params) }, 1000) }) } getApi('start').then((res) => { getApi(res).then((res) => { getApi(res).then((res) => { console.log('finish', res) }) }) })
promise的出現讓異步方法能夠像同步方法那樣返回值,可是並無解決回調地獄的問題,如上面的場景,接下來就該Generator出場了。ajax
es6新增了一種聲明方式,function *api
function*
這種聲明方式(function
關鍵字後跟一個星號)會定義一個 生成器函數(generator function),它返回一個Generator
對象。生成器函數在執行時能暫停,後面又能從暫停處繼續執行。promise
調用一個生成器函數並不會立刻執行它裏面的語句,而是返回一個這個生成器的迭代器 ( iterator)對象。當這個迭代器的
next()
方法被首次(後續)調用時,其內的語句會執行到第一個(後續)出現yield
的位置爲止,yield
後緊跟迭代器要返回的值。或者若是用的是yield*
(多了個星號),則表示將執行權移交給另外一個生成器函數(當前生成器暫停執行)。異步
next()
方法返回一個對象,這個對象包含兩個屬性:value 和 done,value 屬性表示本次yield
表達式的返回值,done 屬性爲布爾類型,表示生成器後續是否還有yield
語句,即生成器函數是否已經執行完畢並返回。async調用
next()
方法時,若是傳入了參數,那麼這個參數會傳給上一條執行的 yield語句左邊的變量函數
運用生成器咱們就能夠這樣去改造上面的例子:
用生成器函數包裹咱們須要處理的語句,在yield後面跟咱們須要處理的promise函數,next()後會執行到下一個yield位置而後暫停當前生成器的執行,至於恢復的時機就是這個promise執行完成(fulfilled/rejected)的時候,這時再調用next(),繼續執行生成器接下來的語句,這裏咱們再實現一個自動運行生成器的方法。代理
function getApi(params) { return new Promise((resolve) => { // 模擬ajax setTimeout(() => { resolve('api result: ' + params) }, 1000) }) } function* gen(stage0) { console.log(stage0) let stage1 = yield getApi('startParams') console.log('stage1', stage1) let stage2 = yield getApi(stage1) console.log('stage2', stage2) let stage3 = yield getApi(stage2) console.log('stage3', stage3) return 'all Done!!' } function run(generator, v) { let { value, done } = generator.next(v) if (!done) { value.then((res) => { run(generator, res) }) } else { console.log(value) } } run(gen('start'))
es2017的新語法,對上面例子的改造就變成了code
function getApi(params) { return new Promise((resolve) => { // 模擬ajax setTimeout(() => { resolve('api result: ' + params) }, 1000) }) } async function getAllApi() { let stage1 = await getApi('startParams') console.log('stage1', stage1) let stage2 = await getApi(stage1) console.log('stage2', stage2) let stage3 = await getApi(stage2) console.log('stage3', stage3) return 'all Done!!' } getAllApi()
因此說async/await
就是generator
+ promise
的語法糖,還自帶auto run的buff對象