摘要:異步編程一般用來調取接口拉數據。通過我描述的篇幅,就知道異步編程比同步編程麻煩許多。遠古時期,異步編程是通過回調函數來解決的。
半理解系列--Promise的進化史
學過js的都知道,程序有同步編程和異步編程之分,同步就好比流水線,一步一個腳印,做完上個任務才做下一個,異步編程好比客服,客服接了一個電話,收到了一個任務,然后把任務交給另外的人來處理,同時,繼續接聽下一個電話,等到另外的人處理完任務了,再通知客服,客服再反饋給第一個打電話的人。異步編程一般用來調取接口拉數據。
通過我描述的篇幅,就知道異步編程比同步編程麻煩許多。遠古時期,異步編程是通過回調函數來解決的。但是回調函數會有回調地獄的問題,回調的多了,維護人員看起來頭都大了,好比:taskC需要等待taskB做完(taskC才執行),taskB又需要等待taskA做完(taskB才執行)
function taskA (cb) { //..do task A cb() } function taskB(cb){ //..do task B cb() } function taskC(cb){ //..do task C cb() } taskA(function(){ taskB(function(){ taskC() }) }) ...以此類推,不斷循環嵌套,最終陷入地獄
而Promise就把這一系列的回調,通過鏈式調用的方式連接起來,看起來清爽多了。同樣是上面的代碼,Promise可以這么寫(偽代碼)
new Promise().then(taskA).then(taskB).then(taskC)promise的使用
const promise = new Promise((resolve,reject)=>{ if (/*do something done*/){ resolve() // 可在此傳參數 } else { // do something fail reject() // 可在此傳參數 } }) promise.then(()=>{ //do something }).catch(e => { throw e})
上面的resolve,可以當作task函數的cb回調函數,當resolve()執行的時候,then方法中的回調會被執行,如果是reject執行,錯誤會被catch捕捉。
Promise的靜態方法
上面說的then和catch都是Promise的原型方法,即Promise.prototype.then/catch
Promise本身有兩個靜態方法,其作用類似 new Promise()
Promise.resolve()
const promise1 = Promise.resolve() 等價于 const promise2 = new Promise((reslove)=>{ reslove() })
使用該方法調用then方法
Promise.reject()
const promise1 = Promise.reject() 等價于 const promise2 = new Promise((resolve,reject)=>{ reject() })
使用該方法會被catch捕捉
Promise的鏈式調用
Promise的實例對象的then方法是可以重復調用的,then方法返回的是一個promise實例對象,所以可以重復調用then方法,并且(敲黑板),上一個then方法的返回值,會作為下一個then方法的參數傳遞
舉個栗子:
const promise = Promise.resolve("start") promise.then((params)=>{ console.log(params) // start return "aa" }).then((params) => { console.log(params) // aa return "bb" }).then((params)=>{ console.log(params) // bb return "cc" }) // 最后會返回一個狀態是resolve(cc)的promise對象:Promise?{: "cc"}
深入一下(又不會懷孕)
function badAsyncCall() { var promise = Promise.resolve(); promise.then(function() { // 任意處理 return "newVar"; }); return promise; } // 修改一下 function goodAsyncCall() { var promise = Promise.resolve(); return promise.then(function() { // 任意處理 return "newWar"; }); }
以上兩個寫法是不是很相似,唯一不同的就是return的處理。但調用,badAsynccall會出錯,而anAsyncCall能正確執行,比如:
badAsyncCall().then(params => { console.log("bad--",params)}) // bad-- undefined goodAsyncCall().then(params => { console.log("good--",params)}) // good-- newWar
分析:第一種,錯誤寫法,首先在 promise.then 中產生的異常不會被外部捕獲,此外,也不能得到 then 的返回值,即使其有返回值。
原因:由于每次 promise.then 調用都會返回一個新創建的promise對象,第一種返回的promise,相當于沒有調用過函數內部的then方法,是一個全新的promise實例對象
結論: 統一使用promise鏈式調用,如:promise.then(taskA).then(taskB)
### async&await和promise的前世緣緣
promise說白了還是用回調的方式來解決異步問題,跟真正同步還是有差距的。
異步編程的最高境界,就是根本不用關心它是不是異步!(來之ruanyifeng老師的話)
所以,async&await方案出現了
用法:
function readFile(fileName) { return new Promise((resolve,reject)=>{ fs.readFile(fileName, function(error, data) { if (error) return reject(error); resolve(data); // 向thenc傳送異步讀取文件的數據 }); }) } // 調用 readFile(fileName).then(function(data){ console.log("prmoise read files data --", data) }) // 等價于 async function asyncFn(fileName){ const data = await readFile(fileName) console.log("await data --", data) return data } asyncFn(fileName)
寫法是不是簡潔了許多!
其實async就是一個Promise的語法糖,它的返回值是一個promise對象,因此可以用then方法做鏈式調用(但參數就是async函數中的返回值,如上文的data!!)
async函數中還可以不使用promise,比如:
async function asyncFn(){ const data = await setTimeout(function(){ console.log("setTimeout") return "data" },1000) console.log("data",data) // Timeout {} 對象 } console.log("async",asyncFn()) // Promise {}
但這兩者,其實經常混用,常見的就是readFile函數的做法啦
看懂以上的,才大家出一道題看看能不能懂;
async function asynFn(){ await Promise.resolve("aaa") const data = { b:"bb", c:function(){ return this.b } } return data //return 作為參數傳遞給then then的chain鏈也是通過return參數來不斷傳遞給后面的then } var cball = asynFn() cball.then(function(data){ console.log("data:",data) })
還有一種異步編程的語法糖: * & yield
跟async基本一樣,不在本文討論的重點。有興趣自行google啦
參考資料:
async 函數的含義和用法
Promise 對象
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/107430.html
摘要:簽訂協議的兩方分別是異步接口和。在異步函數中,使用異常捕獲的方案,代替了的異常捕獲的方案。需要注意的是,在異步函數中使異步函數用時要使用,不然異步函會被同步執行。 同步與異步 通常,代碼是由上往下依次執行的。如果有多個任務,就必需排隊,前一個任務完成,后一個任務才會執行。這種執行模式稱之為: 同步(synchronous) 。新手容易把計算機用語中的同步,和日常用語中的同步弄混淆。如,...
摘要:截至目前,人類大腦是已知宇宙中最復雜的物體。但是天河二號也是一個龐大的家伙,它占地平方米,使用兆瓦的電力大腦只需瓦,耗資億美元建造。建議,通過查看可以以,美元購買多少來考慮計算機的狀態。 showImg(http://upload-images.jianshu.io/upload_images/13825820-c158f685feaf8ae6.jpg?imageMogr2/auto-...
閱讀 1422·2021-11-15 11:38
閱讀 3566·2021-11-09 09:47
閱讀 1969·2021-09-27 13:36
閱讀 3211·2021-09-22 15:17
閱讀 2547·2021-09-13 10:27
閱讀 2862·2019-08-30 15:44
閱讀 1158·2019-08-27 10:53
閱讀 2702·2019-08-26 14:00