亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

談談 ES6 的 Promise 對象

linkin / 1987人閱讀

摘要:一般會這樣去寫要在第一個請求成功后才可以執(zhí)行下一步這樣的寫法的原理是,當執(zhí)行一些異步操作時,我們需要知道操作是否已經完成,所有當執(zhí)行完成的時候會返回一個回調函數(shù),表示操作已經完成。

前言

開篇首先設想一個日常開發(fā)常常會遇到的需求:在多個接口異步請求數(shù)據(jù),然后利用這些數(shù)據(jù)來進行一系列的操作。一般會這樣去寫:

$.ajax({
    url: "......",
    success: function (data) {
        $.ajax({
            // 要在第一個請求成功后才可以執(zhí)行下一步
            url: "......",
            success: function (data) {
                 // ......
            }
        });
    }
});

這樣的寫法的原理是,當執(zhí)行一些異步操作時,我們需要知道操作是否已經完成,所有當執(zhí)行完成的時候會返回一個回調函數(shù),表示操作已經完成。

使用回調函數(shù)的形式理解起來并不困難,但是實際的應用當中會有以下的缺點:

在需要多個操作的時候,會導致多個回調函數(shù)嵌套,導致代碼不夠直觀,就是常說的 Callback Hell。

如果幾個異步操作之間并沒有前后順序之分(例如不需要前一個請求的結果作為后一個請求的參數(shù))時,同樣需要等待上一個操作完成再實行下一個操作。

為了解決上述的問題,Promise 對象應運而生,在 EMCAScript 2015 當中已經成為標準。

什么是 Promise

一個 Promise 對象可以理解為一次將要執(zhí)行的操作(常常被用于異步操作),使用了 Promise 對象之后可以用一種鏈式調用的方式來組織代碼,讓代碼更加直觀。而且由于 Promise.all 這樣的方法存在,可以讓同時執(zhí)行多個操作變得簡單。接下來就來簡單介紹 Promise 對象。

resolve 和 reject

首先來看一段使用了 Promise 對象的代碼。

function helloWorld (ready) {
    return new Promise(function (resolve, reject) {
        if (ready) {
            resolve("Hello World!");
        } else {
            reject("Good bye!");
        }
    });
}

helloWorld(true).then(function (message) {
    alert(message);
}, function (error) {
    alert(error);
});

jsFiddle(請用現(xiàn)代瀏覽器打開)

上面的代碼實現(xiàn)的功能非常簡單,helloWord 函數(shù)接受一個參數(shù),如果為 true 就打印 "Hello World!",如果為 false 就打印錯誤的信息。helloWord 函數(shù)返回的是一個 Promise 對象。

在 Promise 對象當中有兩個重要方法————resolvereject

resolve 方法可以使 Promise 對象的狀態(tài)改變成成功,同時傳遞一個參數(shù)用于后續(xù)成功后的操作,在這個例子當中就是 Hello World! 字符串。

reject 方法則是將 Promise 對象的狀態(tài)改變?yōu)槭。瑫r將錯誤的信息傳遞到后續(xù)錯誤處理的操作。

Promise 的三種狀態(tài)

上面提到了 resolvereject 可以改變 Promise 對象的狀態(tài),那么它究竟有哪些狀態(tài)呢?

Promise 對象有三種狀態(tài):

Fulfilled 可以理解為成功的狀態(tài)

Rejected 可以理解為失敗的狀態(tài)

Pending 既不是 Fulfilld 也不是 Rejected 的狀態(tài),可以理解為 Promise 對象實例創(chuàng)建時候的初始狀態(tài)

helloWorld 的例子中的 then 方法就是根據(jù) Promise 對象的狀態(tài)來確定執(zhí)行的操作,resolve 時執(zhí)行第一個函數(shù)(onFulfilled),reject 時執(zhí)行第二個函數(shù)(onRejected)。

then 和 catch then

helloWorld 的例子當中利用了 then(onFulfilld, onRejected) 方法來執(zhí)行一個任務打印 "Hello World!",在多個任務的情況下 then 方法同樣可以用一個清晰的方式完成。

function printHello (ready) {
    return new Promise(function (resolve, reject) {
        if (ready) {
            resolve("Hello");
        } else {
            reject("Good bye!");
        }
    });
}

function printWorld () {
    alert("World");
}

function printExclamation () {
    alert("!");
}

printHello(true)
    .then(function(message){
        alert(message);
    })
    .then(printWorld)
    .then(printExclamation);

jsFiddle

上述例子通過鏈式調用的方式,按順序打印出了相應的內容。then 可以使用鏈式調用的寫法原因在于,每一次執(zhí)行該方法時總是會返回一個 Promise 對象。另外,在 then onFulfilled 的函數(shù)當中的返回值,可以作為后續(xù)操作的參數(shù),因此上面的例子也可以寫成:

printHello(true).then(function (message) {
    return message;
}).then(function (message) {
    return message  + " World";
}).then(function (message) {
    return message + "!";
}).then(function (message) {
    alert(message);
});

jsFiddle

同樣可以打印出正確的內容。

catch

catch 方法是 then(onFulfilled, onRejected) 方法當中 onRejected 函數(shù)的一個簡單的寫法,也就是說可以寫成 then(fn).catch(fn),相當于 then(fn).then(null, fn)。使用 catch 的寫法比一般的寫法更加清晰明確。

Promise.all 和 Promise.race

Promise.all 可以接收一個元素為 Promise 對象的數(shù)組作為參數(shù),當這個數(shù)組里面所有的 Promise 對象都變?yōu)?resolve 時,該方法才會返回。

var p1 = new Promise(function (resolve) {
    setTimeout(function () {
        resolve("Hello");
    }, 3000);
});

var p2 = new Promise(function (resolve) {
    setTimeout(function () {
        resolve("World");
    }, 1000);
});

Promise.all([p1, p2]).then(function (result) {
    console.log(result); // ["Hello", "World"]
});

上面的例子模擬了傳輸兩個數(shù)據(jù)需要不同的時長,雖然 p2 的速度比 p1 要快,但是 Promise.all 方法會按照數(shù)組里面的順序將結果返回。

日常開發(fā)中經常會遇到這樣的需求,在不同的接口請求數(shù)據(jù)然后拼合成自己所需的數(shù)據(jù),通常這些接口之間沒有關聯(lián)(例如不需要前一個接口的數(shù)據(jù)作為后一個接口的參數(shù)),這個時候 Promise.all 方法就可以派上用場了。

還有一個和 Promise.all 相類似的方法 Promise.race,它同樣接收一個數(shù)組,不同的是只要該數(shù)組中的 Promise 對象的狀態(tài)發(fā)生變化(無論是 resolve 還是 reject)該方法都會返回。

兼容性

最后是關于 Promise 對象的兼容性問題。

在瀏覽器端,一些主流的瀏覽器都已經可以使用 Promise 對象進行開發(fā),在 Node.js 配合 babel 也可以很方便地使用。

如果要兼容舊的瀏覽器,建議可以尋找一些第三方的解決方案,例如 jQuery 的 $.Deferred。

感謝你的閱讀,有不足之處請為我指出。

參考

JavaScript Promise迷你書(中文版)

本文同步于我的個人博客 http://blog.acwong.org/2015/06/22/es6-promise/

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉載請注明本文地址:http://www.ezyhdfw.cn/yun/85753.html

相關文章

  • 談談ES6前后異步編程

    摘要:回調函數(shù)這是異步編程最基本的方法。對象對象是工作組提出的一種規(guī)范,目的是為異步編程提供統(tǒng)一接口。誕生后,出現(xiàn)了函數(shù),它將異步編程帶入了一個全新的階段。 更多詳情點擊http://blog.zhangbing.club/Ja... Javascript 語言的執(zhí)行環(huán)境是單線程的,如果沒有異步編程,根本沒法用,非卡死不可。 為了解決這個問題,Javascript語言將任務的執(zhí)行模式分成兩種...

    fizz 評論0 收藏0
  • 微信小程序踩坑系列——從wx.request談談異步處理

    摘要:其實我們在同步流程中才說返回,異步沒有返回這個概念或者說異步返回是沒有意義的,異步對應的是回調,也就是說,對于一個異步函數(shù),我們應該傳入一個回調函數(shù)來接收結果。 原文鏈接:https://www.xksblog.top/talk-... 見到wx.request的第一眼,就讓我想起了$.ajax這東西,使用起來確實有很多不方便,不能忍,幸好小程序是支持ES6語法的,所以可以使用pro...

    RdouTyping 評論0 收藏0
  • 談談JavaScript異步代碼優(yōu)化

    摘要:異步問題回調地獄首先,我們來看下異步編程中最常見的一種問題,便是回調地獄。同時使用也是異步編程最基礎和核心的一種解決思路?;冢壳耙脖粡V泛運用,其是異步編程的一種解決方案,比傳統(tǒng)的回調函數(shù)解決方案更合理和強大。 關于 微信公眾號:前端呼啦圈(Love-FED) 我的博客:勞卜的博客 知乎專欄:前端呼啦圈 前言 在實際編碼中,我們經常會遇到Javascript代碼異步執(zhí)行的場景...

    chnmagnus 評論0 收藏0
  • JavaScript 異步編程四種方式

    摘要:異步編程是每個使用編程的人都會遇到的問題,無論是前端的請求,或是的各種異步。本文就來總結一下常見的四種處理異步編程的方法。利用一種鏈式調用的方法來組織異步代碼,可以將原來以回調函數(shù)形式調用的代碼改為鏈式調用。 異步編程是每個使用 JavaScript 編程的人都會遇到的問題,無論是前端的 ajax 請求,或是 node 的各種異步 API。本文就來總結一下常見的四種處理異步編程的方法。...

    microelec 評論0 收藏0
  • ES6系列文章 Promise

    摘要:已成功,內部執(zhí)行了方法,實例處于狀態(tài),狀態(tài)不可改變了。實際上是函數(shù)的一種簡寫形式,當執(zhí)行后,可以被的回調函數(shù)接收處理。該語句并未執(zhí)行若內部發(fā)生錯誤,會被自動的執(zhí)行。靜態(tài)函數(shù)返回一個成功的對象,靜態(tài)函數(shù)返回一個拒絕狀態(tài)的對象。 視頻講解 ES6的 Promise 是個啥哩?,是個承諾。為了解決 js 回調地獄。Promise 給我的體會是: 開始云里霧里,然后越用越好用。今天才明白承諾是...

    thekingisalwaysluc 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<