<span id="mktg5"></span>

<i id="mktg5"><meter id="mktg5"></meter></i>

        <label id="mktg5"><meter id="mktg5"></meter></label>
        最新文章專題視頻專題問答1問答10問答100問答1000問答2000關鍵字專題1關鍵字專題50關鍵字專題500關鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關鍵字專題關鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
        問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
        當前位置: 首頁 - 科技 - 知識百科 - 正文

        Javascript Promise用法詳解

        來源:懂視網 責編:小采 時間:2020-11-27 22:14:55
        文檔

        Javascript Promise用法詳解

        Javascript Promise用法詳解:1、約定 本文的 demo 代碼有些是偽代碼,不可以直接執行。 沒有特殊說明,本文所有 demo 都是基于 ES6 規范。 Object.method 代表是靜態方法, Object#method 代表的是實例方法。如 Promise#then 代表的是 Promise 的實例方法, Promi
        推薦度:
        導讀Javascript Promise用法詳解:1、約定 本文的 demo 代碼有些是偽代碼,不可以直接執行。 沒有特殊說明,本文所有 demo 都是基于 ES6 規范。 Object.method 代表是靜態方法, Object#method 代表的是實例方法。如 Promise#then 代表的是 Promise 的實例方法, Promi

        或許你會問,這個操作明明是同步的,定義 Promise 里面的代碼都被立即執行了,那么回調應該緊接著 resolve 函數執行,那么應該先打印 “resolved” 而不應該先打印 “end Promise”.

        這個是 Promise 規范規定的,為了防止同步調用和異步調用同時存在導致的混亂

        6、Promise 的鏈式調用(連貫操作)

        前面我們講過,Promise 的 then 方法以及 catch 方法返回的都是新的 Promise 對象,這樣我們可以非常方便的解決嵌套的回調函數的問題, 也可以很方便的實現流程任務。

        var p = new Promise(function(resolve, reject) {
         resolve();
        });
        function taskA() {
         console.log("Task A");
        }
        function taskB() {
         console.log("Task B");
        }
        function taskC() {
         console.log("Task C");
        }
        p.then(taskA())
        .then(taskB())
        .then(taskC())
        .catch(function(error) {
         console.log(error);
        });
        

        上面這段代碼很方便的實現了從 taskA 到 taskC 的有序執行。

        當然你可以把 taskA - taskC 換成任何異步操作,如從后臺獲取數據:

        var getJSON = function(url, param) {
         var promise = new Promise(function(resolve, reject){
         var request = require('ajax-request');
         request({url:url, data: param}, function(err, res, body) {
         if (!err && res.statusCode == 200) {
         resolve(body);
         } else {
         reject(new Error(err));
         }
         });
         });
        
         return promise;
        };
        var url = "login.php";
        getJSON(url, {id:1}).then(result => {
         console.log(result);
         return getJSON(url, {id:2})
        }).then(result => {
         console.log(result);
         return getJSON(url, {id:3});
        }).then(result => {
         console.log(result);
        }).catch(error => console.log(error));
        
        

        這樣用起來似乎很爽,但是有個問題需要注意,我們說過每個 then() 方法都返回一個新的 Promise 對象,那既然是 Promise 對象,那肯定就有注冊 onFulfilled 和 onRejected, 如果某個任務流程的 then() 方法鏈過長的話,前面的任務拋出異常,會導致后面的任務被跳過。

        function taskA() {
         console.log("Task A");
         throw new Error("throw Error @ Task A");
        }
        function taskB() {
         console.log("Task B");
        }
        function onRejected(error) {
         console.log(error);
        }
        function finalTask() {
         console.log("Final Task");
        }
        var promise = Promise.resolve();
        promise
         .then(taskA)
         .then(taskB)
         .catch(onRejected)
         .then(finalTask);
        

        執行的結果是:

        Task A
        Error: throw Error @ Task A
        Final Task

        顯然, 由于 A 任務拋出異常(執行失敗),導致 .then(taskB) 被跳過,直接進入 .catch 異常處理環節。

        6.1 promise chain 中如何傳遞參數

        上面我們簡單闡述了 Promise 的鏈式調用,能夠非常有效的處理異步的流程任務。

        但是在實際的使用場景中,任務之間通常都是有關聯的,比如 taskB 需要依賴 taskA 的處理結果來執行,這有點類似 Linux 管道機制。 Promise 中處理這個問題也很簡單,那就是在 taskA 中 return 的返回值,會在 taskB 執行時傳給它。

        function taskA() {
         console.log("Task A");
         return "From Task A";
        }
        function taskB(value) {
         console.log(value);
         console.log("Task B");
         return "From Task B";
        }
        function onRejected(error) {
         console.log(error);
        }
        function finalTask(value) {
         console.log(value);
         console.log("Final Task");
        }
        var promise = Promise.resolve();
        promise
         .then(taskA)
         .then(taskB)
         .catch(onRejected)
         .then(finalTask);
        

        搞定,就這么簡單!

        6.2 resolve 和 reject 參數

        reject函數的參數通常是Error對象的實例,表示拋出的錯誤;resolve函數的參數除了正常的值以外,還可能是另一個 Promise 實例, 比如像上面的 getJSON() 方法一樣。

        var p1 = new Promise(function (resolve, reject) {
         setTimeout(() => reject(new Error('fail')), 3000)
        })
        
        var p2 = new Promise(function (resolve, reject) {
         setTimeout(() => resolve(p1), 1000)
        })
        
        p2
         .then(result => console.log(result))
         .catch(error => console.log(error))
        
        

        注意,這時p1的狀態就會傳遞給p2,也就是說,p1的狀態決定了p2的狀態。

        如果p1的狀態是 pending,那么p2的回調函數就會等待p1的狀態改變;

        如果p1的狀態已經是 resolved 或者 rejected,那么p2的回調函數將會立刻執行。

        7、Promise 基本方法

        ES6的Promise API提供的方法不是很多,下面介紹一下 Promise 對象常用的幾個方法.

        7.1 Promise.prototype.catch()

        Promise.prototype.catch方法是.then(null, rejection)的別名,用于指定發生錯誤時的回調函數。

        p.then((val) => console.log('fulfilled:', val))
         .catch((err) => console.log('rejected', err));
        
        // 等同于
        p.then((val) => console.log('fulfilled:', val))
         .then(null, (err) => console.log("rejected:", err));
        

        Promise 對象的錯誤具有“冒泡”性質,會一直向后傳遞,直到被捕獲為止。也就是說,錯誤總是會被下一個catch語句捕獲。 所以通常建議使用 catch 方法去捕獲異常,而不要用 then(null, function(error) {}) 的方式,因為這樣只能捕獲當前 Promise 的異常

        p.then(result => {console.log(result)})
         .then(result => {console.log(result)})
         .then(result => {console.log(result)})
         .catch(error => {
         //捕獲上面三個 Promise 對象產生的異常
         console.log(error);
         });

        跟傳統的try/catch代碼塊不同的是,如果沒有使用catch方法指定錯誤處理的回調函數,Promise 對象拋出的錯誤不會傳遞到外層代碼,即不會有任何反應。

        通俗的說法就是“Promise 會吃掉錯誤”。

        比如下面的代碼就出現這種情況

        var p = new Promise(function(resolve, reject) {
         // 下面一行會報錯,因為x沒有聲明
         resolve(x + 2);
         });
        p.then(() => {console.log("every thing is ok.");});
        // 這行代碼會正常執行,不會受 Promise 里面報錯的影響
        console.log("Ok, it's Great.");
        

        7.2 Promise.all()

        Promise.all方法用于將多個 Promise 實例,包裝成一個新的 Promise 實例。用來處理組合 Promise 的邏輯操作。

        var p = Promise.all([p1, p2, p3]); 

        上面代碼 p 的狀態由p1、p2、p3決定,分成兩種情況。

        1. 只有p1、p2、p3的狀態都變成fulfilled,p的狀態才會變成fulfilled,此時p1、p2、p3的返回值組成一個數組,傳遞給p的回調函數。
        2. 只要p1、p2、p3之中有一個被rejected,p的狀態就變成rejected,此時第一個被reject的實例的返回值,會傳遞給p的回調函數。

        下面是一個具體的例子

        // 生成一個Promise對象的數組
        var promises = [1,2,3,4,5,6].map(function (id) {
         return getJSON('/post/' + id + ".json");
        });
        
        Promise.all(promises).then(function (posts) {
         // ...
        }).catch(function(reason){
         // ...
        });
        
        

        上面代碼中,promises 是包含6個 Promise 實例的數組,只有這6個實例的狀態都變成 fulfilled,或者其中有一個變為 rejected, 才會調用 Promise.all 方法后面的回調函數。

        7.3 Promise.race()

        Promise.race方法同樣是將多個Promise實例,包裝成一個新的Promise實例。 與 Promise.all 不同的是,只要有一個 promise 對象進入 FulFilled 或者 Rejected 狀態的話,Promise.rece 就會繼續進行后面的處理

        var p = Promise.race([p1, p2, p3]);

        上面代碼中,只要p1、p2、p3之中有一個實例率先改變狀態,p的狀態就跟著改變。那個率先改變的 Promise 實例的返回值,就傳遞給p的回調函數。 Promise.race 方法的參數與 Promise.all 方法一樣,如果不是 Promise 實例,就會先調用 Promise.resolve 方法, 將參數轉為 Promise 實例,再進一步處理。

        下面是一個具體的例子

        // `delay`毫秒后執行resolve
        function timerPromisefy(delay) {
         return new Promise(function (resolve) {
         setTimeout(function () {
         resolve(delay);
         }, delay);
         });
        }
        // 任何一個promise變為resolve或reject 的話程序就停止運行
        Promise.race([
         timerPromisefy(1),
         timerPromisefy(32),
         timerPromisefy(64),
         timerPromisefy(128)
        ]).then(function (value) {
         console.log(value); // => 1
        });
        

        7.4 Promise.resolve()

        Promise.resolve 方法有2個作用,一個就是前面我們說的,它是通過靜態方法創建 Promise 實例的渠道之一, 另一個作用就是將 Thenable 對象轉換為 Promise 對象。

        那么什么是 Thenable 對象呢?ES6 Promises里提到了Thenable這個概念,簡單來說它就是一個非常類似promise的東西。 就像我們有時稱具有 .length 方法的非數組對象為 Array like 一樣,Thenable 指的是一個具有 .then 方法的對象。

        這種將 Thenable對象轉換為 Promise 對象的機制要求thenable對象所擁有的 then 方法應該和Promise所擁有的 then 方法具有同樣的功能和處理過程, 在將 Thenable 對象轉換為 Promise 對象的時候,還會巧妙的利用 Thenable 對象原來具有的 then 方法。

        到底什么樣的對象能算是 Thenable 的呢,最簡單的例子就是 jQuery.ajax(),它的返回值就是 Thenable 的。

        將 Thenable 對象轉換為 Promise 對象

        var promise = Promise.resolve($.ajax('/json/comment.json'));// => promise對象
        promise.then(function(value){
         console.log(value);
        });
        

        除了上面的方法之外,Promise.resolve方法的參數還有以下三種情況。

        (1). 參數是一個 Promise 實例

        如果參數是Promise實例,那么Promise.resolve將不做任何修改、原封不動地返回這個實例。

        (2). 參數不是具有then方法的對象,或根本就不是對象

        如果參數是一個原始值,或者是一個不具有then方法的對象,則Promise.resolve方法返回一個新的Promise對象,狀態為resolved。

        var p = Promise.resolve('Hello');
        p.then(function (s){
         console.log(s)
        });

        上面代碼生成一個新的Promise對象的實例p。由于字符串Hello不屬于異步操作(判斷方法是字符串對象不具有then方法), 返回Promise實例的狀態從一生成就是resolved,所以回調函數會立即執行。 Promise.resolve方法的參數,會同時傳給回調函數。

        (3). 不帶有任何參數

        Promise.resolve方法允許調用時不帶參數,直接返回一個resolved狀態的Promise對象。這個我們在上面講創建 Promise 實例的三種方法的時候就講過了

        var p = Promise.resolve();
        p.then(function () {
         // ...
        });
        

        7.5 Promise.reject()

        Promise.reject(reason)方法也會返回一個新的 Promise 實例,該實例的狀態為rejected。 需要注意的是,Promise.reject()方法的參數,會原封不動地作為 reject 的理由,變成后續方法的參數。這一點與 Promise.resolve 方法不一致。

        const thenable = {
         then(resolve, reject) {
         reject('出錯了');
         }
        };
        
        Promise.reject(thenable)
        .catch(e => {
         console.log(e === thenable)
        })
        // true
        
        

        上面代碼中,Promise.reject 方法的參數是一個 thenable 對象,執行以后,后面 catch 方法的參數不是 reject 拋出的“出錯了”這個字符串, 而是 thenable 對象。

        聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

        文檔

        Javascript Promise用法詳解

        Javascript Promise用法詳解:1、約定 本文的 demo 代碼有些是偽代碼,不可以直接執行。 沒有特殊說明,本文所有 demo 都是基于 ES6 規范。 Object.method 代表是靜態方法, Object#method 代表的是實例方法。如 Promise#then 代表的是 Promise 的實例方法, Promi
        推薦度:
        標簽: 使用 用法 js
        • 熱門焦點

        最新推薦

        猜你喜歡

        熱門推薦

        專題
        Top
        主站蜘蛛池模板: 国产成人AV免费观看| 成年免费大片黄在线观看岛国| 一级毛片免费全部播放| 免费无码又爽又刺激一高潮| 亚洲成A∨人片天堂网无码| 无码乱人伦一区二区亚洲| 亚洲天堂一区在线| caoporn国产精品免费| 1000部拍拍拍18勿入免费视频软件 | 免费国产在线观看老王影院| 久久亚洲精品成人综合| 国产免费网站看v片在线| 国产亚洲精品xxx| 男男黄GAY片免费网站WWW| 国产99视频精品免费专区| 免费国产小视频在线观看| 黄页网址在线免费观看| 成年在线观看免费人视频草莓| 亚洲av日韩av不卡在线观看 | 67194成手机免费观看| 亚洲国产成人精品女人久久久 | 噜噜噜亚洲色成人网站∨| 三级片免费观看久久| 毛片在线看免费版| 久久综合亚洲鲁鲁五月天| 亚洲免费观看网站| 亚洲经典千人经典日产| 久久精品网站免费观看| 亚洲AV电影天堂男人的天堂| 99久久综合国产精品免费| 亚洲精品成a人在线观看夫| 亚洲精品一级无码鲁丝片| 成人亚洲国产精品久久| 日本免费一区尤物| 亚洲人成色4444在线观看| 国产电影午夜成年免费视频| 2022年亚洲午夜一区二区福利| 天天看片天天爽_免费播放| 亚洲日韩av无码中文| 亚洲中文无韩国r级电影| a级毛片免费高清视频|