Promise的總結
Promise作為Nodejs的曾經的黑科技,一直優待著銳意寫出漂亮程式碼的人們。簡而言之,其解決了一個回撥陷阱的問題,Nodejs作為以回撥為品牌的語言平臺,其一直得益於其瘋狂的回撥模式,網上更有各種評測,其以單執行緒支撐萬計的訪問量,頗有點喬峰在聚賢莊的意思。
假設這麼一個場景:我們需要讀取檔案中的資料,然後提取其中我們需要的資訊,傳送到後臺程式中,並接收其結果。程式碼示意如下:
fs.readFile('aaa.txt', function(content, e){ if(e){ console.info("開啟檔案失敗"); return; } let name = content.substring(3,55); sendToOther(name, function(e){ if(e){ console.info("you lost!"); }else { console.info("你成功啦"); } }); });
其實上面的程式碼看著還行,但是如果我在你成功之後,需要將寫日誌,日誌書寫失敗,需要發簡訊,簡訊傳送成功與否,需要記錄,以備未來計費。。。
如果一直回撥下去,我估計已經沒有人能回得來神了。試想,我們在看原始碼的時候,經常頭疼的就是呼叫棧,看到裡面,想不起外面的上下文是什麼情況,又從debugger裡點出來,看外面一層的方法呼叫的上下文,以及其想幹個啥。
那麼Promise就是為了解決此問題,而出現的。上程式碼:
首先要明白,鏈式呼叫,現在許多程式,尤其是一些cs的程式都喜歡這個調調,其核心就是被設定或處理的主體即this,會在處理完成後返回。
那麼上面的程式,我們如何進行Promise呢。
new Promise(function(resolve, reject){ fs.readFile('aaa.txt', function(content){ if(e){ reject("開啟檔案失敗"); return ; } resolve(content); // 以下程式會立即執行,不會等待resolve返回的 console.info("I will be printed right now!!!!!") }).then(function(content){ let name = content.substring(3,55); return name; }).then(function(name){ // ******1****** return new Promise(function(resolve, reject)){ sendToOther(name, function(e){ if(e){ console.info("you lost!"); reject("lost when sendToOther"); }else { console.info("你成功啦"); resolve("ok"); } }); } }).then(function(ok)){ //ok is ok // go to send sms }catch(function(e){ console.error(e); }); });
由上述程式碼,可以知道,其實首個方法,用new Promise來解決,其裡面的回撥裡,可以用then來解決同步的呼叫,如果想用 then來解決非同步的回撥,這時候,要動用then裡返回Promise的方法來重新開始。
所以有兩個地方要明確:
1、then方法時要兩個引數,當然後者經常省略。用typescript的限制寫法,可以如下:
fufilled:(a:any)=>any
failed:(a:any)=>any
ps:then中的函式,只能來傳傳遞一個引數,不能是多個
那麼,以下的方法都可以認為是第一個引數有值,第二個沒值
如果想重新連起來,就弄個函式,接收上面的引數,並且返回一個Promise
2、如果想處理then中的回撥,需要用新的Promise來返回
3、注意程式執行順序,跟在resolve和reject後的內容會立即執行,不是等你的resolve返回後才執行。所以可以理解,Promise僅來協調resolve和then中指定的程式碼執行順序。