成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

ES6 Promise - Promise的生命周期和創(chuàng)建

Hydrogen / 2290人閱讀

摘要:通過(guò)構(gòu)造函數(shù),可以創(chuàng)建一個(gè)。函數(shù)本身是一個(gè)異步行為,其方法的第三個(gè)參數(shù)為一個(gè)回調(diào)函數(shù),用來(lái)接收文件讀取的結(jié)果失敗時(shí)候的和成功時(shí)候的。第一個(gè)函數(shù)的參數(shù)對(duì)應(yīng)的參數(shù),第二個(gè)回調(diào)函數(shù)對(duì)應(yīng)的參數(shù)。

一:Promise的概念

Promise的中文意思是‘承諾’,什么叫承諾?承諾就是現(xiàn)在沒有發(fā)生,在將來(lái)的某個(gè)時(shí)刻一定會(huì)發(fā)生的事情。
放在編程語(yǔ)言的環(huán)境下,Promise就是異步事件的結(jié)果的占位符。我們不用去管異步事件的結(jié)果什么時(shí)候來(lái),只需要關(guān)心異步事件的結(jié)果產(chǎn)生的時(shí)候,你想要做什么就對(duì)了。

二:Promise的生命周期

異步事件不是立即執(zhí)行程序,它的結(jié)果可能要在動(dòng)作發(fā)生后一段時(shí)間才到,所以它有個(gè)生命周期。例如用電飯鍋煮米飯,從【米下鍋開始定時(shí)】到【定時(shí)結(jié)束】,這是煮米飯的生命周期。
一個(gè)Promise的生命周期主要有2個(gè)階段:

1: unsettled(pending) 處理過(guò)程中 -> 米飯定時(shí)開始到定時(shí)結(jié)束這段期間
2: settled (fulfilled或者rejected) 處理完 -> 米飯定時(shí)結(jié)束狀態(tài)

我們看到settled階段會(huì)出現(xiàn)兩個(gè)可能的狀態(tài)fulfilled或者rejected,它們分別是什么意思呢:

1: fulfilled Promise操作完成的結(jié)果為成功 -> 煮米飯水的比例合適,飯熟了,成功
2: rejected Promise操作完成的結(jié)果為失敗 -> 煮米飯水放少了,飯是夾生的,失敗

Promise內(nèi)部的屬性PromiseState被用來(lái)表示Promise的3種狀態(tài):pending,fulfilled 和 rejected。但是我們無(wú)法讀取到這三個(gè)狀態(tài),而是通過(guò)Promise提供的接口方法來(lái)書寫對(duì)應(yīng)的處理程序,后面會(huì)講到。

三:如何讓創(chuàng)建一個(gè)Promise
相信前面通過(guò)對(duì)比煮飯這個(gè)過(guò)程,你已經(jīng)對(duì)Promise的概念和生命周期有了一定的體會(huì),接下來(lái)我們就看看如何真正第創(chuàng)建一個(gè)Promise(如何煮米飯)。

聲明:因?yàn)镻romise有未完成的Promise已完成的Promise不同類型,本篇我們只討論未完成的Promise。已完成的Promise后面會(huì)講,目前來(lái)說(shuō)你不必關(guān)心,就當(dāng)世界上沒有這個(gè)東西。

通過(guò)Promise構(gòu)造函數(shù),可以創(chuàng)建一個(gè)Promise。構(gòu)造函數(shù)只有一個(gè)參數(shù):一個(gè)函數(shù),我們叫它執(zhí)行器(executor)函數(shù)。你可以理解為煮飯用的電飯煲。

既然執(zhí)行器(executor)函數(shù)也是一個(gè)函數(shù),那它也有參數(shù)。對(duì),它有2個(gè)參數(shù):

1: resolve() 執(zhí)行器(executor)函數(shù)成功時(shí)的處理函數(shù)
2: reject() 執(zhí)行器(executor)函數(shù)失敗時(shí)的處理函數(shù)

我們用一段代碼來(lái)解釋一下:

let executor = function (resolve, reject) {};
let promise = new Promise(executor);

通過(guò)上面的代碼示例,應(yīng)該就能很清楚創(chuàng)建一個(gè)Promise的語(yǔ)法解構(gòu)是怎樣的了。接下來(lái)我們用一個(gè)在Node.js中讀取文件的例子來(lái)演示:

let executor = function (resolve, reject) {
    let fs = require("fs");
    fs.readFile("data.txt", {encoding: "utf8"}, function (error, content) {
        if (error) {
            reject(error); //在異步行為失敗時(shí),調(diào)用reject()方法
            return;
        }
        resolve(content); //在異步行為成功時(shí),調(diào)用resolve()方法

    });
};
let promise = new Promise(executor);

解釋一下上面的代碼:

1: 創(chuàng)建Promise,包裹異步程序

Promise本身并不執(zhí)行任何真正的異步程序。我們只是把異步程序包裹在一個(gè)Promise里面,這樣做的目的其實(shí)是想把異步處理程序的結(jié)果給Promise,稍后再利用Promise提供的接口函數(shù)(then()或者catch())來(lái)對(duì)結(jié)果進(jìn)行處理。

2: 我們?cè)赑romise的executor函數(shù)里調(diào)用真正的異步操作函數(shù)。

我們?cè)趀xecutor函數(shù)里調(diào)用fs.readFile( )函數(shù)。fs.readFile( )函數(shù)本身是一個(gè)異步行為,其方法的第三個(gè)參數(shù)為一個(gè)回調(diào)函數(shù),用來(lái)接收文件讀取的結(jié)果(失敗時(shí)候的error和成功時(shí)候的content)。

3: 把異步程序的結(jié)果給Promise

我們?cè)趂s.readFile( )的回調(diào)函數(shù)里,在文件讀取成功時(shí)調(diào)用resolve( )方法,失敗的時(shí)候調(diào)用reject( )方法,把成功或者失敗的結(jié)果通過(guò)2個(gè)函數(shù)的參數(shù)傳入,為Promise在fulfilled或者rejected兩種狀態(tài)時(shí)提供數(shù)據(jù)。

四:編寫Promise結(jié)果處理程序

前面我們已經(jīng)了解到了怎么把一個(gè)異步處理事件包裹在一個(gè)Promise里面,并且通過(guò)resolve()和reject()把異步處理事件的結(jié)果傳遞的過(guò)程。終于來(lái)到了最后一步:使用結(jié)果數(shù)據(jù)(對(duì)比現(xiàn)實(shí)生活,你也可以理解為這一步叫做:驗(yàn)證承諾)。
Promise提供2個(gè)方法來(lái)處理結(jié)果: Promise.prototype.then()Promise.prototype.catch()。我們分別來(lái)看一下二者的功能:

1:Promise.prototype.then()

then()方法接收2個(gè)函數(shù)類行的參數(shù):

1: 第一個(gè)參數(shù)為Promise在fulfilled狀態(tài)(成功狀態(tài))時(shí)的回調(diào)方法
2: 第一個(gè)參數(shù)為Promise在rejected狀態(tài)(失敗狀態(tài))時(shí)的回調(diào)方法

我們以之前的讀取文件為例子,看一下then()方法的使用:

let executor = function (resolve, reject) {
    let fs = require("fs");
    fs.readFile("data.txt", {encoding: "utf8"}, function (error, content) {
        if (error) {
            reject(error); //在異步行為成功時(shí),調(diào)用reject()方法
            return;
        }
        resolve(content); //在異步行為失敗時(shí),調(diào)用resolve()方法

    });
};
let promise = new Promise(executor);

//處理成功和失敗的情況
promise.then(function (content) {
    console.log(content);

}, function (error) {
    console.log(error)
});

這兩個(gè)回調(diào)函數(shù)的參數(shù)也就是之前異步處理的結(jié)果數(shù)據(jù)。第一個(gè)函數(shù)的參數(shù)對(duì)應(yīng)resolve()的參數(shù)content,第二個(gè)回調(diào)函數(shù)對(duì)應(yīng)reject()的參數(shù)error。這樣我們也就能在這2個(gè)回調(diào)函數(shù)里面拿到數(shù)據(jù),從而根據(jù)你的業(yè)務(wù)需求編寫對(duì)應(yīng)的結(jié)果處理程序。

需要說(shuō)明的是,這兩個(gè)回調(diào)函數(shù)參數(shù)都不是必須的,并不強(qiáng)制要求你都要處理。下面的代碼里,列覺了某2種結(jié)果處理程序,語(yǔ)法上都是合法的。只是正常的需求下,我們一般還是需要對(duì)成功和失敗都要處理。

 //只處理成功的情況
promise.then(function (content) {
    console.log(content);

});
//只處理失敗的情況
promise.then(null, function (error) {
    console.log(error)
});
2: Promise.prototype.catch()

catch()方法只有一個(gè)參數(shù):一個(gè)只處理rejected狀態(tài)的回調(diào)函數(shù)??赡軙?huì)有人疑問,then()已經(jīng)可以同時(shí)處理2個(gè)狀態(tài),為什么還需要catch()方法?

原因在于前面我們提到的,在then()方法里,并不強(qiáng)制要求你提供處理rejected的回調(diào)函數(shù)。Promise有個(gè)特性:如果你沒有添加rejected處理函數(shù),那所有的失敗會(huì)被自動(dòng)忽略。

可能會(huì)有些開發(fā)者只關(guān)心成功狀態(tài),而忘了提供rejected處理函數(shù),從而給整個(gè)程序埋下隱患,這樣會(huì)造成很不好的用戶體驗(yàn)。而catch()方法就是一個(gè)明確地處理rejected的方法,而不像在then()里面,因?yàn)槭欠潜仨殔?shù)而讓人很容易忽略。

背景說(shuō)了那么多,我們看看catch()怎么用:

promise.catch(function (error) {
    console.log(error)
})

其實(shí)用法很簡(jiǎn)單,它其實(shí)等價(jià)于是有reject處理函數(shù)的then():

promise.then(null, function (error) {
    console.log(error)
});

沒有語(yǔ)法要求一個(gè)完整的Promise處理程序必須要有catch()方法。如果你沒有使用catch()的習(xí)慣,最好總是不要忘記在使用then()的時(shí)候添加reject處理函數(shù)。

或者,如果你偶爾會(huì)忘記在then()里添加reject處理函數(shù),那么記得使用catch()來(lái)為你做最安全的保障。

以上,就是關(guān)于Promise的基本概念和使用。在平常的開發(fā)中,Promise的使用還是非常頻繁的,也很好用,所以我認(rèn)為掌握Promise是一個(gè)必須的功課。

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/106310.html

相關(guān)文章

  • 深入理解ES6筆記(十一)Promise與異步編程

    摘要:回調(diào)函數(shù)模式類似于事件模型,因?yàn)楫惒酱a也會(huì)在后面的一個(gè)時(shí)間點(diǎn)才執(zhí)行如果回調(diào)過(guò)多,會(huì)陷入回調(diào)地獄基礎(chǔ)可以當(dāng)做是一個(gè)占位符,表示異步操作的執(zhí)行結(jié)果。函數(shù)可以返回一個(gè),而不必訂閱一個(gè)事件或者向函數(shù)傳遞一個(gè)回調(diào)函數(shù)。 主要知識(shí)點(diǎn):Promise生命周期、Promise基本操作、Promise鏈、響應(yīng)多個(gè)Promise以及集成PromiseshowImg(https://segmentfaul...

    RayKr 評(píng)論0 收藏0
  • 《深入理解ES6》筆記—— Promise與異步編程(11)

    摘要:為什么要異步編程我們?cè)趯懬岸舜a時(shí),經(jīng)常會(huì)對(duì)做事件處理操作,比如點(diǎn)擊激活焦點(diǎn)失去焦點(diǎn)等再比如我們用請(qǐng)求數(shù)據(jù),使用回調(diào)函數(shù)獲取返回值。這些都屬于異步編程?;卣{(diào)有多個(gè)狀態(tài),當(dāng)響應(yīng)成功和失敗都有不同的回調(diào)函數(shù)。 為什么要異步編程 我們?cè)趯懬岸舜a時(shí),經(jīng)常會(huì)對(duì)dom做事件處理操作,比如點(diǎn)擊、激活焦點(diǎn)、失去焦點(diǎn)等;再比如我們用ajax請(qǐng)求數(shù)據(jù),使用回調(diào)函數(shù)獲取返回值。這些都屬于異步編程。 也許你...

    ssshooter 評(píng)論0 收藏0
  • 《深入理解ES6》筆記—— Promise與異步編程(11)

    摘要:為什么要異步編程我們?cè)趯懬岸舜a時(shí),經(jīng)常會(huì)對(duì)做事件處理操作,比如點(diǎn)擊激活焦點(diǎn)失去焦點(diǎn)等再比如我們用請(qǐng)求數(shù)據(jù),使用回調(diào)函數(shù)獲取返回值。這些都屬于異步編程?;卣{(diào)有多個(gè)狀態(tài),當(dāng)響應(yīng)成功和失敗都有不同的回調(diào)函數(shù)。 為什么要異步編程 我們?cè)趯懬岸舜a時(shí),經(jīng)常會(huì)對(duì)dom做事件處理操作,比如點(diǎn)擊、激活焦點(diǎn)、失去焦點(diǎn)等;再比如我們用ajax請(qǐng)求數(shù)據(jù),使用回調(diào)函數(shù)獲取返回值。這些都屬于異步編程。 也許你...

    YacaToy 評(píng)論0 收藏0
  • 高級(jí)前端面試題大匯總(只有試題,沒有答案)

    摘要:面試題來(lái)源于網(wǎng)絡(luò),看一下高級(jí)前端的面試題,可以知道自己和高級(jí)前端的差距。 面試題來(lái)源于網(wǎng)絡(luò),看一下高級(jí)前端的面試題,可以知道自己和高級(jí)前端的差距。有些面試題會(huì)重復(fù)。 使用過(guò)的koa2中間件 koa-body原理 介紹自己寫過(guò)的中間件 有沒有涉及到Cluster 介紹pm2 master掛了的話pm2怎么處理 如何和MySQL進(jìn)行通信 React聲明周期及自己的理解 如何...

    kviccn 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<