站長資訊網
        最全最豐富的資訊網站

        實例解析ES6 Promise的原理和使用

        1. Promise 之前

        1.1 回調函數

        回調函數:把函數A當作參數傳遞給另一個函數B調用,那么A就是回調函數。【推薦:JavaScript視頻教程】

        一些例子
        具名回調

        function 你有幾只狗(fn){     fn('一只狗') }function 數狗(數量){     console.log(數量) } 你有幾只狗(數狗)   // 一只狗

        匿名回調

        function 你有幾只狗(fn){     fn('一只狗') } 你有幾只狗(function(數量){console.log(數量)  })         //  一只狗

        常見的例子
        jQuery中使用回調函數,這里用的是匿名回調的方式

        $("#btn").click(function(){     console.log('點到我了') })

        1.2 回調地獄(回調缺點1)

        回調地獄:指的是回調嵌套過多的情況,導致代碼很難被看懂。

        let info = []function 你有幾只狗(fn){     fn('一只狗') }function 你有幾只貓(fn){     fn('一只貓') }function 知道了(數量,callback){     info.push(數量)     console.log(info)    if(callback){         callback()     } }// 開始調用 如果比這再多幾層,就不容易看懂了你有幾只狗(function(狗數){     console.log(狗數)     知道了(狗數, function(){         你有幾只貓(function(貓數){             console.log(貓數)             知道了(貓數)         })     }) })

        1.3 不使用Promise,如何解決

        利用具名函數代替匿名函數

        let info = []function 你有幾只狗(fn){     fn('一只狗') }function 你有幾只貓(fn){     fn('一只貓') }function 知道了(數量,callback){     info.push(數量)     console.log(info)    if(callback){         callback()     } }function 告訴你貓的個數(貓數){     console.log(貓數)     知道了(貓數) }function 繼續數(){     你有幾只貓(告訴你貓的個數) }function 告訴你狗的個數(狗數){     console.log(狗數)     知道了(狗數, 繼續數) } 你有幾只狗(告訴你狗的個數)  // 好像也沒好到哪去。。。

        1.4 回調方式各不相同,需要單獨記憶(回調缺點2)

        readFile('C:\1.txt',function (error, data) {   // node.js 讀取文件方法中的回調         if(error) {             console.log('成功')             console.log(data.toString())         } else {             console.log('讀取文件失敗')         }     })  $.ajax({                              // jQuery中ajax方法中的回調     url:'/2.txt'     success: function(response) {         console.log('成功')     },     error: function(){         console.log('失敗')     } })

        2. Promise 的目的

        Promise 是異步編程的一種解決方案,比傳統的解決方案——回調函數和事件——更合理和更強大。它由社區最早提出和實現,ES6 將其寫進了語言標準,統一了用法,原生提供了Promise對象。

        3. Promise 的原理

        3.1 實現原理

        ES6 規定,Promise對象是一個構造函數,用來生成Promise實例。通過在函數內部return 一個 Promise對象的實例,這樣就可以使用Promise的屬性和方法進行下一步操作了。

        function 函數名(){    return new Promise(function(resolve, reject) {         // ... some code          if (/* 異步操作成功 */){             resolve(value);   // 異步操作成功時調用,把結果作為參數傳遞出去           } else {             reject(error);     // 異步失敗時調用,把錯誤作為參數傳遞出去           }      }) }

        3.2 調用邏輯

        實例解析ES6 Promise的原理和使用
        S1和E1兩個都沒有報錯,執行S2(resolve執行,系統認為搞定了,沒報錯)
        S1和E1任何一個有報錯,執行E2(reject執行,系統認為沒搞定,報錯了)

        4. Promise 的使用

        4.1 Promise 的屬性與方法

        屬性
        Promise.prototype 表示 Promise 構造器的原型
        方法
        Promise.prototype.then()
        返回一個 Promise 。它最多需要有兩個參數:Promise 的成功和失敗情況的回調函數。
        Promise.prototype.catch()
        返回一個Promise,并且處理拒絕的情況。等價于Promise.prototype.then(undefined, onRejected)
        Promise.prototype.finally()
        finally() 方法返回一個Promise,在執行then()和catch()后,都會執行finally指定的回調函數。避免同樣的語句需要在then()和catch()中各寫一次的情況。
        Promise.all(iterable)
        返回一個 Promise 實例,iterable參數內所有的 promise 都resolved后,才回調完成resolve。
        Promise.race(iterable)
        返回一個 promise ,并伴隨著 promise對象解決的返回值或拒絕的錯誤原因, 只要 iterable 中有一個 promise 對象”解決(resolve)”或”拒絕(reject)”。
        Promise.resolve()
        返回一個以給定值解析后的Promise對象。但如果這個值是個thenable(即帶有then方法),返回的promise會“跟隨”這個thenable的對象,采用它的最終狀態(指resolved/rejected/pending/settled);如果傳入的value本身就是promise對象,則該對象作為Promise.resolve方法的返回值返回;否則以該值為成功狀態返回promise對象。
        Promise.reject()
        返回一個帶有拒絕原因reason參數的Promise對象。

        4.2 將回調地獄中的例子,改寫為Promise的形式

        實例解析ES6 Promise的原理和使用
        可以看到使用 Promise后,邏輯變得非常直觀
        寫得更完整一些
        實例解析ES6 Promise的原理和使用
        Promise套Promise時,也就是Promise鏈的時候——注意信息的傳遞
        一個失敗的例子,當我們使用Promise鏈的時候,如果每一步都需要上一步的數據時,就需要傳參,成功通過resolve傳參,失敗通過reject傳參,如果忘記傳參,就得不到想要的結果。
        resolve把成功的數據返回給下一個回調
        reject把失敗的數據返回給下一個回調。
        實例解析ES6 Promise的原理和使用
        給這里的resolve傳一個參
        實例解析ES6 Promise的原理和使用
        改成失敗的例子
        先不給reject傳參,如果失敗的話,下一個回調拿不到數據
        實例解析ES6 Promise的原理和使用
        給 reject傳參
        實例解析ES6 Promise的原理和使用
        我們可以看到,即使是走的失敗回調,下一個成功回調還是執行了,由于 不知道() 默認返回undefined, 相當于失敗已經處理了,在成功和失敗都被處理的情況下,下一個回調會執行的。
        改成符合預期的,即失敗不調用。
        實例解析ES6 Promise的原理和使用
        失敗不調用的簡寫形式
        實例解析ES6 Promise的原理和使用
        上述情況執行后 .then(除了狗呢)里面的成功回調沒有執行,我們增加一個失敗回調看看
        實例解析ES6 Promise的原理和使用
        同樣也可以返回 resolve,讓后面成功回調可以執行
        實例解析ES6 Promise的原理和使用

        4.3 應用

        加載圖片
        將圖片的加載寫成一個Promise,一旦加載完成,Promise的狀態就發生變化。

        const preloadImage = function (path) {   return new Promise(function (resolve, reject) {     const image = new Image();     image.onload  = resolve;     image.onerror = reject;     image.src = path;   }); };

        Generator 函數與 Promise 的結合(詳情見參考鏈接,阮一峰的教程)

        5. 干掉Promise中的回調

        5.1 await

        成功的情況
        實例解析ES6 Promise的原理和使用
        失敗的情況
        利用 try catch
        實例解析ES6 Promise的原理和使用
        await 配合 try catch使用,比較完整

        6. 總結

        能利用Promise對象,把普通函數改成返回Promise的形式,解決回調地獄的問題。
        明白Promise的成功失敗調用邏輯,可以靈活的進行調整。
        理解核心知識,先用起來,慢慢整合吸收知識。

        贊(0)
        分享到: 更多 (0)
        網站地圖   滬ICP備18035694號-2    滬公網安備31011702889846號
        主站蜘蛛池模板: 亚洲精品无码永久中文字幕| 丰满人妻熟妇乱又仑精品| 亚洲精品国产成人片| 青青草国产精品| 久久99国产精品尤物| 亚洲国产小视频精品久久久三级 | 蜜臀久久99精品久久久久久| 你懂的国产精品| 91精品国产91久久久久福利| 亚洲精品成人片在线观看精品字幕 | 亚洲精品成人av在线| 全球AV集中精品导航福利| 精品无码人妻久久久久久| 91精品国产91久久久久久青草| 99精品视频在线观看| 久久久久成人精品无码中文字幕 | 18国产精品白浆在线观看免费| 亚洲AV无码成人精品区在线观看| 欧美成人精品高清在线播放| 国语自产精品视频| 国产精品免费αv视频| 99精品电影一区二区免费看| 日本人精品video黑人| 国产精品视频免费观看| 国产99久久精品一区二区| 精品无码国产污污污免费网站| 亚洲国产精品18久久久久久| 亚洲欧洲精品成人久久奇米网| 日韩精品电影一区亚洲| 欧美久久亚洲精品| 欧美精品色精品一区二区三区| 国产激情精品一区二区三区| 日韩精品在线视频| 亚洲精品综合一二三区在线| 在线人成精品免费视频| 亚洲精品无码AV中文字幕电影网站| 久久精品国产亚洲欧美| 国产精品亚洲不卡一区二区三区 | 久久精品人人槡人妻人人玩AV | 91精品成人免费国产| 国产精品无码久久久久久|