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

資訊專欄INFORMATION COLUMN

Promise學(xué)習(xí)總結(jié)

twohappy / 549人閱讀

摘要:引擎線程也稱為內(nèi)核,負(fù)責(zé)處理腳本程序例如引擎引擎線程負(fù)責(zé)解析腳本,運(yùn)行代碼。對象代表一個未完成但預(yù)計(jì)將來會完成的操作。注意一旦新建就會立即執(zhí)行它屬于,無法取消。

寫在前面:
第一遍學(xué)Promise時, 只是大概過了一遍, 感覺學(xué)的不夠深入, 這一篇算是對之前的一個總結(jié)吧. Promise在ES6中也屬于一個較難理解的一部分; 所以在學(xué)習(xí)一個比較難理解的知識點(diǎn)時, 我們可以圍繞這個知識點(diǎn)進(jìn)行展開,逐個去理解.

再探Promise

理解一個知識點(diǎn), 不妨先列出下面幾個問題.

Promise是用來干什么的?

Promise是什么?

Promise如何去創(chuàng)建,使用?

Promise的常用形式?

Promise的使用有哪些注意點(diǎn)?

異步相關(guān)背景介紹 瀏覽器內(nèi)核

首先聊一下瀏覽器, 一直對瀏覽器的結(jié)構(gòu)比較好奇,查了很多資料總結(jié)就有下面一點(diǎn)相關(guān)總結(jié); 其中也借鑒其他人的一些東西.
瀏覽器是多進(jìn)程的,有主進(jìn)程, GPU加速進(jìn)程,渲染進(jìn)程(內(nèi)核)等, 一般新開一個tab頁面就是新啟動一個進(jìn)程, CPU就會給他分配資源; 但其中有一個核心進(jìn)程==>渲染進(jìn)程(瀏覽器內(nèi)核), 是我們前端人員需要特別關(guān)注的,它包括了多個線程...

GUI渲染線程

負(fù)責(zé)渲染瀏覽器界面,解析HTML,CSS,構(gòu)建DOM樹和RenderObject樹,布局和繪制等。
當(dāng)界面需要重繪(Repaint)或由于某種操作引發(fā)回流(reflow)時,該線程就會執(zhí)行

注意,GUI渲染線程與JS引擎線程是互斥的,當(dāng)JS引擎執(zhí)行時GUI線程會被掛起(相當(dāng)于被凍結(jié)了),
GUI更新會被保存在一個隊(duì)列中等到JS引擎空閑時立即被執(zhí)行。

JS引擎線程

也稱為JS內(nèi)核,負(fù)責(zé)處理Javascript腳本程序.(例如V8引擎)JS引擎線程負(fù)責(zé)解析Javascript腳本,運(yùn)行代碼。
JS引擎一直等待著任務(wù)隊(duì)列中任務(wù)的到來,然后加以處理,一個Tab頁(renderer進(jìn)程)中無論什么時候都只有一個JS線程在運(yùn)行JS程序
同樣注意,GUI渲染線程與JS引擎線程是互斥的,所以如果JS執(zhí)行的時間過長,這樣就會造成頁面的渲染不連貫,導(dǎo)致頁面渲染加載阻塞。

不過H5中新增了Web Worker, 實(shí)現(xiàn)了多線程: js會新開線程來處理一些其他任務(wù),但不會影響DOM結(jié)構(gòu)...
創(chuàng)建Worker時,JS引擎向?yàn)g覽器申請開一個子線程(子線程是瀏覽器開的,完全受主線程控制,而且不能操作DOM)
JS引擎線程與worker線程間通過特定的方式通信
(postMessage API,需要通過序列化對象來與線程交互特定的數(shù)據(jù))

事件觸發(fā)線程

這個線程是歸屬于瀏覽器而不是JS引擎,用來控制事件循環(huán)(可以理解,JS引擎自己都忙不過來,需要瀏覽器另開線程協(xié)助)
當(dāng)JS引擎執(zhí)行代碼塊如setTimeOut時(也可來自瀏覽器內(nèi)核的其他線程,如鼠標(biāo)點(diǎn)擊、AJAX異步請求,
頁面滾動等),會將對應(yīng)任務(wù)添加到事件線程中
當(dāng)對應(yīng)的事件符合觸發(fā)條件被觸發(fā)時,該線程會把事件添加到待處理隊(duì)列的隊(duì)尾,等待JS引擎的處理
注意,
由于JS的單線程關(guān)系,所以這些待處理隊(duì)列中的事件都得排隊(duì)等待JS引擎處理(當(dāng)JS引擎空閑時才會去執(zhí)行)

定時觸發(fā)器線程

即setInterval與setTimeout所在線程
瀏覽器定時計(jì)數(shù)器并不是由JavaScript引擎計(jì)數(shù)的,(因?yàn)镴avaScript引擎是單線程的, 如果處于阻塞線程狀態(tài)就會影響記計(jì)時的準(zhǔn)確); 
因此通過多帶帶線程來計(jì)時并觸發(fā)定時(計(jì)時完畢后,添加到事件隊(duì)列中,等待JS引擎空閑后執(zhí)行)
當(dāng)然setTimeout中的延時參數(shù)也不一定準(zhǔn)確

異步HTTP請求線程

在XMLHttpRequest在連接后是通過瀏覽器新開一個網(wǎng)絡(luò)線程去請求
將檢測到狀態(tài)變更時,如果設(shè)置有回調(diào)函數(shù),異步線程就產(chǎn)生狀態(tài)變更事件,
將這個回調(diào)再放入事件隊(duì)列中。再由JavaScript引擎執(zhí)行。

那么關(guān)于瀏覽器方面的背景知識就介紹到這里啦, 想要深入去了解,可以去查相關(guān)資料...

事件隊(duì)列和循環(huán)

大家都知道JavaScript引擎是單線程的工作模式, 即同一時間只能跑一段代碼,還要按順序自上而下執(zhí)行; 但是碰到I/O操作, 定時器, 事件監(jiān)聽函數(shù)等這些耗時操作; JS引擎不會等待它們有結(jié)果了才去之下它們后面的代碼, 而是會將它們?nèi)舆M(jìn)任務(wù)(事件)隊(duì)列中, 等待同步代碼執(zhí)行棧空了之后, 再去任務(wù)隊(duì)列將任務(wù)一個個取出來執(zhí)行任務(wù)所對應(yīng)的回調(diào)函數(shù), 執(zhí)行完畢后會一直等待新的任務(wù)到來; 如此循環(huán)...

幾個類型的回調(diào)

同步回調(diào)函數(shù)

我們可以利用了函數(shù)的執(zhí)行棧順序,函數(shù)作為參數(shù)放到另一個函數(shù)中調(diào)用, 誰在后面調(diào)用誰就先被放在函數(shù)執(zhí)行棧棧頂

異步回調(diào)函數(shù)

事先在外面定義好一個callback; 將回調(diào)函數(shù)作為某個函數(shù)的參數(shù), 利用函數(shù)的作用域?qū)⒑瘮?shù)中異步任務(wù)得到的結(jié)果存在回調(diào)函數(shù)的形參中, 然后在函數(shù)體末尾調(diào)用...

定時器
setTimeout的作用是在間隔一定的時間后,將回調(diào)函數(shù)插入任務(wù)隊(duì)列中,等棧中的同步任務(wù)都執(zhí)行完畢后,再執(zhí)行, 當(dāng)然這個時間不一定準(zhǔn)確...

Promise是用來干什么的?

看阮老師的ES6出門上說Promise是JS異步編程的一種解決方案. 舉個例子, Ajax的回調(diào)問題, 如果下一個ajax請求要用到上一個Ajax請求中的結(jié)果, 那么往往就會導(dǎo)致多個回調(diào)嵌套的問題, 那么Promise就可以解決這種代碼上的嵌套問題, 是我們的代碼變得更優(yōu)美, 更利于維護(hù); 我暫時先對Promise的理解就是: 處理異步任務(wù), 保存異步結(jié)果狀態(tài), 異步代碼同步化...

Promise是什么?

Promise 它就是一個對象,相當(dāng)于一個容器, 里面存的就是一個異步操作的結(jié)果; 我們可以是從中獲取異步操作結(jié)果的相關(guān)信息。

Promise對象代表一個未完成、但預(yù)計(jì)將來會完成的操作。
它有以下三種狀態(tài):

pending:初始值,不是fulfilled,也不是rejected
fulfilled:代表操作成功
rejected:代表操作失敗

Promise有兩種狀態(tài)改變的方式,既可以從pending轉(zhuǎn)變?yōu)閒ulfilled,也可以從pending轉(zhuǎn)變?yōu)閞ejected。一旦狀態(tài)改變,就「凝固」了,會一直保持這個狀態(tài),不會再發(fā)生變化。當(dāng)狀態(tài)發(fā)生變化,promise.then綁定的函數(shù)就會被調(diào)用。
注意:Promise一旦新建就會「立即執(zhí)行」(它屬于microtask),無法取消。這也是它的缺點(diǎn)之一。

Promise的創(chuàng)建和使用?

1.創(chuàng)建promise對象

//1.使用new Promise(func)的形式
//2.快捷語法: Promise.resolve(func) || Promise.reject(func)
// 參數(shù)1: 一般是一個處理異步任務(wù)的函數(shù)  
// 返回值: 一個promise實(shí)例對象
Promise.resolve("foo")
// 等價于, 不過參數(shù)類型不一樣執(zhí)行的操作也會有所不同
new Promise(resolve => resolve("foo"))

2.在函數(shù)func中 放異步處理代碼

// 傳入兩個參數(shù): 回調(diào)函數(shù)resolve, reject分別去保存異步處理的結(jié)果
// 成功: 使用resolve(結(jié)果)
// 失敗: 使用reject(原因) 

3.調(diào)用實(shí)例的then(func1) 或者 catch(err)

首先then方法是異步執(zhí)行, 對上面的異步結(jié)果進(jìn)行處理的函數(shù)
參數(shù): 傳回調(diào)函數(shù), 一個兩個都行, 前者是成功狀態(tài)的回調(diào),后者是失敗的回調(diào)
Promise常用的場景?

promise一般的使用套路就是:

1.先定義一個函數(shù), 函數(shù)內(nèi)部使用new Promise()的方式來返回一個promise對象, resolve用來保存 異步處理成功的結(jié)果
reject用來保存 異常處理的結(jié)果
2.然后函數(shù)調(diào)用,傳參
3.鏈?zhǔn)秸Z法點(diǎn)出then方法, then中的回調(diào)用來處理異步結(jié)果
4.有錯誤就點(diǎn)出catch方法, 也可以用then(null, function() {})代替catch
5.then的回調(diào)中也可return一個值, 會被包裝成一個新的promise, 因此可以繼續(xù)調(diào)用then方法

應(yīng)用場景: 在ajax中使用, 解決異步嵌套問題

    function ajax(url) {

        return new Promise((resolve, reject) => {
    
            let xhr = new XMLHttpRequest();
            // 請求類型, 地址, 異步
            xhr.open("get", url, true);
            xhr.send();
            xhr.onreadystatechange = function () {
                if (xhr.readyState === 4 && xhr.status === 200) {
                    try {
                        // 處理響應(yīng)內(nèi)容, 將內(nèi)容丟到成功狀態(tài)的回調(diào)
                        resolve(JSON.parse(xhr.responseText))
                    } catch (e) {
                        // 捕獲錯誤, 丟到失敗狀態(tài)的回調(diào)
                        reject(e)
                    }
                }
            }
        });
    }

    // 調(diào)用 封裝的ajax函數(shù)
    let url = "http://127.0.0.1:3000/xxoo"; // 自己本地開的一個服務(wù)

    ajax(url)
        .then(res => console.log(res)) // 輸出 {code: 0, msg: "hello cors"}
        .catch(err => console.log(err))

```

其他場景

    // 實(shí)現(xiàn)串行任務(wù)管道; 即當(dāng)前任務(wù)的輸出可以作為下一個任務(wù)的輸入,形成一條數(shù)據(jù)管道;
    // 比如: 比如從url1獲取參數(shù)userId,拿到后再從url2獲取第三方openId,最后再從url3貨取orderList,
    然后把結(jié)果展示給用戶,類似的邏輯都是任務(wù)管道:
    
    new Promise(function(resolve, reject) {
        resolve(1);
    })
    .then(function(res) {
        return new Promise(function(resolve, reject) {
            resolve(res + 1);
        });
    })
    .then(function(res) {
        return new Promise(function(resolve, reject) {
            resolve(res + 1);
        });
    })
        .then(function(res) {
        console.log(res); // 3
    });

promise的好處

在異步執(zhí)行的流程中,使用Promise可以把 執(zhí)行代碼 和 處理結(jié)果 的代碼清晰地分離
這樣我們便可以 把執(zhí)行代碼 和 結(jié)果處理 分成不同的模塊來寫,易于維護(hù)

減少異步回調(diào)的嵌套, 比如ajax回調(diào), 我們可以依次調(diào)用then方法即可, 還可以控制回調(diào)的順序

多個異步任務(wù)是為了容錯去訪問用同一資源時, 可以使用Promise.race([promise實(shí)例...])

多個異步任務(wù)并行執(zhí)行時,比如ajax訪問兩個接口, 可以用Promise.all([promise實(shí)例...])

Promise使用的注意事項(xiàng)

Promise構(gòu)造函數(shù)內(nèi)的同步代碼立即執(zhí)行

回調(diào)函數(shù)參數(shù)resolve異步執(zhí)行, 將結(jié)果作為參數(shù)傳給then方法中的回調(diào)函數(shù)

resolve只有第一次執(zhí)行有效,狀態(tài)不能二次改變

then和catch如果有return, 返回的是一個全新的promise對象, 可以鏈?zhǔn)秸{(diào)用

Promise構(gòu)造函數(shù)只會執(zhí)行一次, promise實(shí)例會保存resolve的狀態(tài),
以后這個實(shí)例每次調(diào)用then都是返回一個這個狀態(tài), 若鏈?zhǔn)秸{(diào)用then,下一個則會打印undefined, res沒有值...

then中返回任意一個非 promise 的值都會被包裹成 promise 對象

.then 或 .catch 返回的值不能是 promise 本身,否則會造成死循環(huán)

.then 或者 .catch 的參數(shù)期望是函數(shù),傳入非函數(shù)則會發(fā)生值穿透。

.then 可以接收兩個參數(shù),第一個是處理成功的函數(shù),第二個是處理錯誤的函數(shù)。.catch 是 .then 第二個參數(shù)的簡便寫法,但是它們用法上有一點(diǎn)需要注意:.then 的第二個處理錯誤的函數(shù)捕獲不了第一個處理成功的函數(shù)拋出的錯誤,而后續(xù)的 .catch 可以捕獲之前的錯誤。

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

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

相關(guān)文章

  • promise以及async、await學(xué)習(xí)總結(jié)

    Promise/async、await幫我們解決了什么 它給我們提供了一種新的異步編程解決方案,同時避免了困擾已久的回調(diào)地獄 // 異步的處理可能會產(chǎn)生這樣的回調(diào)地獄(第二個異步操作和第一個異步的結(jié)果有關(guān)系) let Ajax = function(data, success, error){ $.ajax({ data: data, success: function...

    zero 評論0 收藏0
  • promise以及async、await學(xué)習(xí)總結(jié)

    Promise/async、await幫我們解決了什么 它給我們提供了一種新的異步編程解決方案,同時避免了困擾已久的回調(diào)地獄 // 異步的處理可能會產(chǎn)生這樣的回調(diào)地獄(第二個異步操作和第一個異步的結(jié)果有關(guān)系) let Ajax = function(data, success, error){ $.ajax({ data: data, success: function...

    mist14 評論0 收藏0
  • promise以及async、await學(xué)習(xí)總結(jié)

    Promise/async、await幫我們解決了什么 它給我們提供了一種新的異步編程解決方案,同時避免了困擾已久的回調(diào)地獄 // 異步的處理可能會產(chǎn)生這樣的回調(diào)地獄(第二個異步操作和第一個異步的結(jié)果有關(guān)系) let Ajax = function(data, success, error){ $.ajax({ data: data, success: function...

    fuchenxuan 評論0 收藏0
  • ES6-7

    摘要:的翻譯文檔由的維護(hù)很多人說,阮老師已經(jīng)有一本關(guān)于的書了入門,覺得看看這本書就足夠了。前端的異步解決方案之和異步編程模式在前端開發(fā)過程中,顯得越來越重要。為了讓編程更美好,我們就需要引入來降低異步編程的復(fù)雜性。 JavaScript Promise 迷你書(中文版) 超詳細(xì)介紹promise的gitbook,看完再不會promise...... 本書的目的是以目前還在制定中的ECMASc...

    mudiyouyou 評論0 收藏0
  • Promise學(xué)習(xí)總結(jié)與思考

    摘要:學(xué)習(xí)地址詳見正文調(diào)用或并不會終結(jié)的參數(shù)函數(shù)的執(zhí)行調(diào)用以后,后面的還是會執(zhí)行,并且會首先打印出來。這是因?yàn)榱⒓吹氖窃诒据喪录h(huán)的末尾執(zhí)行,總是晚于本輪循環(huán)的同步任務(wù)。另外,方法指定的回調(diào)函數(shù),如果運(yùn)行中拋出錯誤,也會被方法捕獲。 學(xué)習(xí)地址詳見:http://es6.ruanyifeng.com/#do... 正文 1.調(diào)用resolve或reject并不會終結(jié) Promise 的參數(shù)函...

    canopus4u 評論0 收藏0

發(fā)表評論

0條評論

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