摘要:函數(shù)會在異步操作成功完成時被調(diào)用,并將異步操作的返回值作為參數(shù)傳遞到外部。方法的返回值方法總是返回一個新的對象,多次調(diào)用方法,默認(rèn)返回一個一個空的對象使用來來返回。
promise是什么
官網(wǎng)解釋 promise 表示一個異步操作的最終結(jié)果。
翻譯 ==可以將promise理解為一個狀態(tài)機==,它存在三種不同的狀態(tài),并在某一時刻只能有一種狀態(tài)
pending 表示還在執(zhí)行
resolved 執(zhí)行成功
rejected 執(zhí)行失敗
一個promise是對一個異步操作的封裝,異步操作有等待完成、成功和失敗三種可能的結(jié)果,對應(yīng)了promise的三種狀態(tài)。
promise的狀態(tài)只能有pending轉(zhuǎn)換位resolved或者pending轉(zhuǎn)換為rejected,一旦狀態(tài)轉(zhuǎn)化完成就無法再改變。
假設(shè)我們用promise封了一個異步操作,那么當(dāng)它被創(chuàng)建的時候就處于pending狀態(tài),當(dāng)異步操作成功完成時,
我們將狀態(tài)轉(zhuǎn)換為resolved,如果執(zhí)行中出現(xiàn)錯誤,將狀態(tài)轉(zhuǎn)換為rejected。
var promise=new Promise(function(resolve,reject){ // code if(){ /*異步操作成功 */ resolve(value) }else{ reject(error) } })
var fs=require("fs") function readFile_promise(path){ return new Promise(function(resolve,reject){ fs.readFile(path, "utf-8",function(err,data){ if(data){ resolve(data) }else{ reject(err) } }) }) } var result=readFile_promise("./1.txt") result.then(function(value){ //success console.log("success", value) },function(error){ //failure console.log("failure",error) }) // 將一個異步函數(shù)封裝成promise,只要在回調(diào)函數(shù)中針對不同的返回結(jié)果調(diào)用resolve或者reject方法。 // resolve函數(shù)會在異步操作成功完成時被調(diào)用,并將異步操作的返回值作為參數(shù)傳遞到外部。 // reject是在異步操作出現(xiàn)異常時被調(diào)用,會將錯誤信息作為參數(shù)傳遞出去。
then方法總是返回一個新的promise對象,多次調(diào)用then方法,默認(rèn)返回一個一個空的promise對象
使用return來來返回。
var promise=readFile_promise("./foo.txt") promise.then(function(value){ //success console.log("success", value) // foo return readFile_promise("./bar.txt") },function(error){ //failure console.log("failure",error) }).then(function(value){ console.log("then", value) // bar })
雖然我們是通過then方法來獲取promise的結(jié)果,但是promise是當(dāng)then方法調(diào)用之后才執(zhí)行嗎?
var promise=new Promise((resolve, reject)=>{ console.log("begin") resolve() }) setTimeout(()=>{ promise.then(()=>{ console.log("end") }) },5000) // 開始begin 5s后end // 運行順序是,當(dāng)promise從被創(chuàng)建的那一刻起就開始執(zhí)行了,then方法只是提供了訪問promise狀態(tài)的接口,與promise的執(zhí)行無關(guān)。
resolved
rejected
all
race 方法接收一個promise數(shù)組作為參數(shù)并返回一個新的promise,數(shù)組中的promise會同時開始執(zhí)行,race返回的promise的狀態(tài)有數(shù)組中率先執(zhí)行完畢的promise的狀態(tài)決定
catch 執(zhí)行出錯可以使用throw關(guān)鍵字拋出錯誤,并使用catch方法進(jìn)行捕獲
// 如果有多個promise需要執(zhí)行,可以使用promise.all() // 方法統(tǒng)一聲明,改方法可以將多個promise對象包裝成一個promise // 該方法接收一個數(shù)組作為參數(shù),數(shù)據(jù)的元素如果不是promise對象,則回先調(diào)用resolve方法轉(zhuǎn)換。 // 如果中間有一個promise狀態(tài)是reject,那么轉(zhuǎn)換后的promise也會變成reject,并且將錯誤信息傳給catch方法 var promises=["foo.txt","bar.txt","baz.txt"] promises.map(function(path){ // console.log(path) return readFile_promise(path) }) Promise.all(promises).then(function(results){ console.log(results) // [ "foo.txt", "bar.txt", "baz.txt" ] 順序排列的 }).catch(function(err){ // })
// 例子; 有三個文本文件需要順序讀取 var lists=["foo.txt","bar.txt","baz.txt"] var count=0; readFile_promise("foo.txt").then(readCB).then(readCB).then(readCB); function readCB(data){ console.log(data) // foo bar baz if(++count>2){ return } return readFile_promise(lists[count]) }async/await
await關(guān)鍵字后面往往是一個promise,如果不是就隱式調(diào)用promise.resolve來轉(zhuǎn)換成一個promise。
await 等待后面的promise執(zhí)行完成再進(jìn)行下一步操作。
var asyncReadFile=async function(){ var result1=await readFile_promise("./foo.txt") console.log(result1.toString()) // foo } asyncReadFile()
async函數(shù)總是會返回一個promise對象,如果return關(guān)鍵字后面不是一個promise,那么默認(rèn)
調(diào)用promise。resolve方法進(jìn)行轉(zhuǎn)換。
async function asyncFunc(){ return "hello Node" } asyncFunc().then(function(data){ console.log(data) // hello Node })
在async函數(shù)開始執(zhí)行的時候回自動生成一個promise對象。
當(dāng)方法體開始執(zhí)行后,如果遇到return關(guān)鍵字或者throw關(guān)鍵字,執(zhí)行會立刻退出,
如果遇到await關(guān)鍵字則回暫停執(zhí)行 await后面的異步操作結(jié)束后會恢復(fù)執(zhí)行
執(zhí)行完畢,返回一個promise
async function asyncFunc(){ console.log("begin") return "hello Node" } asyncFunc().then(function(data){ console.log(data) // hello Node console.log("end") }) // begin // hello // end
await 操作符的結(jié)果是由其后面promise對象的操作結(jié)果來決定的,如果后面promise對象變?yōu)閞esolved,
await操作符發(fā)返回的值就是resolve的值;如果promise對象的狀態(tài)變成rejected,那么await也會拋出reject的值。
async function readFile(){ var result=await readFile_promise("./foo.txt") console.log(result) // foo } readFile() // 等價于 readFile_promise("foo.txt").then(function(data){ console.log(data) // foo })
await會等待后面的promise完成后再采取下一步動作,這意味著當(dāng)多個await操作時,程序會便成完全的
串行操作。
當(dāng)異步操作之間不存在依賴關(guān)系時,可以使用promise.all來實現(xiàn)并行。
async function readFile(){ const [result1, result2]=await Promise.all([ readFile_promise("./foo.txt"), readFile_promise("./bar.txt") ]) console.log(result1, result2) // foo bar } readFile() // 等價于 function readFile(){ return Promise.all([ readFile_promise("./foo.txt"), readFile_promise("./baz.txt") ]).then((result)=>{ console.log(result) // [ "foo", "baz" ] }) } readFile()await 總結(jié)
await關(guān)鍵字使用的一些關(guān)鍵點
await關(guān)鍵字必須位于async函數(shù)內(nèi)部
await關(guān)鍵字后面需要是一個promise對象(不是的話就調(diào)用了resolve轉(zhuǎn)換的)
await關(guān)鍵字的返回結(jié)果就是在其后面promise執(zhí)行的結(jié)果,可能是resolved或者rejected的值
不能在普通箭頭函數(shù)中使用await關(guān)鍵字,需要在箭頭函數(shù)前面加上async關(guān)鍵字。
await用來串行地執(zhí)行異步操作,想實現(xiàn)并行使用promise.all
async函數(shù) 的缺點假設(shè)我們有很多層的方法調(diào)用,最底層的異步操作被封裝成了async方法,那么該函數(shù)的所有上層方法可能都要變成async方法。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/102879.html
摘要:顯然,了解的實現(xiàn)細(xì)節(jié),可以幫助我們更好地應(yīng)用它。本文將主要根據(jù)的這篇文章,探討的實現(xiàn)細(xì)節(jié)。核心說明盡管已經(jīng)有自己的規(guī)范,但目前的各類庫,在的實現(xiàn)細(xì)節(jié)上是有差異的,部分甚至在意義上完全不同。到前面到為止,所實現(xiàn)的都是不能級聯(lián)的。 在之前的異步JavaScript與Promise一文中,我介紹了Promise以及它在異步JavaScript中的使用意義。一般來說,我們是通過各種JavaSc...
摘要:對于和的理解今天碰到問題是這樣子的調(diào)試的時候發(fā)現(xiàn)走了也走了有在我印象里是走了就不該走后來發(fā)現(xiàn)是我理解錯了代碼是這樣的這個的是里的異常,里如果有任何異常都會被捕獲仔細(xì)看了是這樣解釋的簡單來講調(diào)用等于調(diào)用由于返回的是一個對象,返回值解釋如下如果 對于Promise.then()和Promise.catch()的理解 今天碰到問題是這樣子的:調(diào)試bug的時候發(fā)現(xiàn)axios走了then也走了有...
摘要:理解回調(diào)和原文自工程師博客,傳送門這兩個概念是編程語言的基本內(nèi)容。回調(diào)地獄就是濫用回調(diào)。通常,在回調(diào)中,錯誤作為第一個參數(shù)傳遞。這個具有這兩個函數(shù)作為參數(shù)的回調(diào)稱為執(zhí)行程序。到目前為止,我希望我已經(jīng)讓自己了解了回調(diào)和。 理解回調(diào)和Promise 原文自工程師Fernando Hernandez博客,傳送門 這兩個概念是Javascript編程語言的基本內(nèi)容。因為這種語言是在異步編程的...
摘要:從最開始的到封裝后的都在試圖解決異步編程過程中的問題。為了讓編程更美好,我們就需要引入來降低異步編程的復(fù)雜性。寫一個符合規(guī)范并可配合使用的寫一個符合規(guī)范并可配合使用的理解的工作原理采用回調(diào)函數(shù)來處理異步編程。 JavaScript怎么使用循環(huán)代替(異步)遞歸 問題描述 在開發(fā)過程中,遇到一個需求:在系統(tǒng)初始化時通過http獲取一個第三方服務(wù)器端的列表,第三方服務(wù)器提供了一個接口,可通過...
摘要:一個就像一個樂高玩具。問題是不是你小時候玩兒的那個有趣,它們不是充滿想象力的打氣筒,也不是一種樂高玩具。這是對的并不是給開發(fā)者使用的,它們是給庫作者使用的。不會超過這兩種情況。第二個是根據(jù)第一個處理函數(shù)如何運行來自動變成狀態(tài)成功或者失敗。 原文地址:http://blog.getify.com/promis... 在 Part4:擴展問題 中,我討論了如何擴展和抽象Promise是多么...
閱讀 1961·2021-09-09 09:33
閱讀 1107·2019-08-30 15:43
閱讀 2645·2019-08-30 13:45
閱讀 3297·2019-08-29 11:00
閱讀 845·2019-08-26 14:01
閱讀 3558·2019-08-26 13:24
閱讀 471·2019-08-26 11:56
閱讀 2683·2019-08-26 10:27