国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

【ES6腳丫系列】Promise

BoYang / 1521人閱讀

摘要:三種狀態進行中已完成,又稱已失敗。如果的狀態是,那么的回調函數就會等待的狀態改變,在此之前不會有結果。等價于例子例子的概念是實例的別名,用于指定發生錯誤時的回調函數。

『ES6知識點總結』變量的解構賦值

本文主要內容如下:
1 Promise是什么?
1.1 特點:
1.2 三種狀態:
1.3 用處:
1.4 Promise缺點:
1.5 歷史過程
2 生成promise實例
3 promise實例的then()方法
4 resolve函數的參數可以是另一個Promise實例
5 Promise的方法(多種)
5.1 Promise.all()
5.2 Promise.race()
5.3 Promise.reject(reason)
5.4 Promise.resolve(obj)
6 Promise.prototype.catch()的概念
6.1 盡量不定義then的reject方法
6.2 catch方法返回的還是一個Promise對象,因此后面還可以接著調用then方法。
7
7.1 如果前面的promise和then()沒有報錯,則會跳過catch方法。
7.2 拋錯的冒泡性質
7.2.1 如果Promise狀態已經變成resolved,再拋出錯誤是無效的。
7.2.2 Promise在下一輪“事件循環”再拋出錯誤
7.2.3 如果沒有處理錯誤的回調函數,就沒有反應
7.2.4 catch方法之中,還能再拋出錯誤。
8 node.js的unhandledRejection
9 done()
10 finally()

Promise是什么?
01、是一個對象,用來傳遞異步操作的消息。
02、代表了某個未來才會知道結果的事件(通常是一個異步操作)。
03、提供一個統一的API,可以進一步處理,控制異步操作。

特點:

01、對象的狀態不受外界影響。

02、代表一個異步操作。

三種狀態:

Pending(進行中)
Resolved(已完成,又稱Fulfilled)
Rejected(已失敗)。

(1)默認的Promise對象是等待態(Pending)。
只有異步操作的結果,可以決定當前是哪一種狀態,任何其他操作都無法改變這個狀態。
這也是Promise這個名字的由來,它的英語意思就是“許諾”,表示其他手段無法改變。

(2)一旦狀態改變了,就不會再變了,會一直保持這個結果。
任何時候都可以得到這個結果。

Promise對象的狀態改變,只有兩種:

從Pending變為Resolved。
從Pending變為Rejected。

這與事件(Event)不同,事件的特點是,如果你錯過了它,再去監聽,是得不到結果的。

用處:
用Promise對象可以將異步操作以同步操作的流程表達出來,避免了層層嵌套的回調函數。
可以判斷多個異步事件的完成,

Promise缺點:
無法取消Promise,一旦新建它就會立即執行,無法中途取消。
如果不設置回調函數,Promise內部拋出的錯誤,不會反應到外部。
當處于Pending狀態時,無法得知目前進展到哪一個階段(剛剛開始還是即將完成)。

歷史過程

生成promise實例
Promise是一個構造函數,可以生成Promise實例。

接受一個函數A作為參數,該函數A有2個參數,是resolve和reject(拒絕),它們是函數,由JS引擎提供,不用自己部署。

resolve(value)函數的作用是,將Promise對象的狀態從“未完成”變為“成功”(即從Pending變為Resolved),在異步操作成功時被調用,并將異步操作的結果,作為自己的參數。

reject(error)函數的作用是,將Promise對象的狀態從“未完成”變為“失敗”(即從Pending變為Rejected),在異步操作失敗時調用,并將異步操作報出的錯誤,作為自己的參數。

reject函數的參數通常是Error對象的實例,表示拋出的錯誤。

例子:
reject(new Error(this.statusText));

在promise實例的構造函數中,可以只返回resolve(value)或reject(error);
例子:
let pro = new Promise((resolve,reject)=>{resolve(value)});

寫法:
創造了一個Promise實例。

const promise = new Promise(function(resolve, reject) {
    if ( /* 異步操作成功 */ ) { resolve(value); } 
    else { reject(error); }
});

promise實例的then()方法
這個方法在實例的狀態改變時會觸發它的參數函數。
當promise實例轉為成功(Resolved)狀態時,觸發then()的第一個函數參數。
當promise實例轉為失敗(Rejected)狀態時,觸發then()的第二個函數參數。(第二個函數參數可選)

這兩個函數參數都接受promise實例傳出的值作為參數。也就是resolve(value)和reject(value)的value值。

then()方法是定義在原型對象Promise.prototype上的,被所有promise實例繼承。

promise.then(
    function (value) { // success
    },
    function (value) { // failure
    }
);

箭頭函數方式:
promise.then( (value)=>{}, (error)=>{} )

如果then()中有設置新的promise實例,則then()方法返回這個promise對象。
否則將默認構建一個新的promise對象,并繼承調用then()方法的promise的狀態(成功或失敗)。

then方法return返回的是一個新的Promise實例(注意,不是原來那個Promise實例)。
因此可以采用鏈式寫法,即then方法后面再調用另一個then方法。

這個函數返回undefined,則then()方法構建一個默認的Promise對象,并且這個對象擁有then()方法所屬的Promise對象的狀態。

var p = new Promise(function (resolve) {
        resolve();//直接標志執行態
    }), temp;
temp = p.then(function () {
        //傳入執行態函數,不返回值
    });
 temp.then(function () {
        console.log("fulfilled");//擁有p的狀態
    });
console.log(temp === p);//默認構建的promise,但已經和p不是同一個對象,輸出false

如果對應狀態所執行的函數返回一個全新的Promise對象,則會覆蓋掉當前Promise,代碼如下:

var p = new Promise(function (resolve) {
    resolve();//直接標志執行態
}), temp;
temp = p.then(function () {
    //返回新的promise對象,和p的狀態無關
    return new Promise(function (resolve, reject) {
        reject();//標志拒絕態
    });
});
temp.then(function () {
    console.log("fulfilled");
}, function () {
    console.log("rejected");//輸出rejected
});




resolve函數的參數可以是另一個Promise實例
表示當前異步操作的取決于另一個異步操作的結果。
舉個例子來說,張三到李四家拿鑰匙,取決于李四在家不在家。
如果李四在家,那么張三可以成功拿到鑰匙。如果李四不在家,張三就拿不到鑰匙。

有2個promise實例p1和p2,
p2的resolve(p1),那么,p1的狀態決定了p2的狀態。
如果p1的狀態是Pending,那么p2的回調函數就會等待p1的狀態改變,在此之前不會有結果。
如果p1的狀態已經是Resolved或者Rejected,那么p2的回調函數將會立刻執行。

比如像下面這樣。

var p1 = new Promise(function(resolve, reject) { // ...});
var p2 = new Promise(function(resolve, reject) { // ...
    resolve(p1);
})

【】例子:
p1是一個Promise,3秒之后變為rejected。p2的狀態由p1決定,1秒之后,p2調用resolve方法,但是此時p1的狀態還沒有改變,因此p2的狀態也不會變。又過了2秒,p1變為rejected,p2也跟著變為rejected。

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))
p2.catch(error => console.log(error))
    // Error: fail

【】例子:
下面是一個Promise對象的簡單例子。
timeout函數中,會返回新生成的Promise實例,其中,定時器setTimeout會在100ms后調用resolve("done");當調用resolve后,觸發then綁定的回調函數。
zyx456:"done"是resolve的參數。
等效于:

function timeout(ms) {
    return new Promise((resolve, reject) => {
        setTimeout(resolve("done"),ms);
    });
}
timeout(100).then((value) => {
    console.log(value);
});




【】例子:
下面是異步加載圖片的例子。

function loadImageAsync(url) {

return new Promise(function(resolve, reject) {
    var image = new Image();
    image.onload = function() { resolve(image); };
    image.onerror = function() { reject(new Error("Could not load image at " + url)); };
    image.src = url;
});

}

【】例子:
下面是一個用Promise對象實現的Ajax操作的例子。
getJSON是對XMLHttpRequest對象的封裝,用于發出一個針對JSON數據的HTTP請求,并且返回一個Promise對象。

var getJSON = function (url) {
var promise = new Promise(function (resolve, reject) {
    var client = new XMLHttpRequest();
    client.open("GET", url);
    client.onreadystatechange = handler;
    client.responseType = "json";
    client.setRequestHeader("Accept", "application/json");
    client.send();

    function handler() {
        if (this.readyState !== 4) {
            return;
        }
        if (this.status === 200) {
            resolve(this.response);
        } else {
            reject(new Error(this.statusText));
        }
    };
});
return promise;
};
getJSON("/posts.json").then(function (json) {
    console.log("Contents: " + json);
}, function (error) {
    console.error("出錯了", error);
});

箭頭函數寫法:

getJSON("/post/1.json").then(
post => getJSON(post.commentURL)).then(
comments => console.log("Resolved: ", comments),
err => console.log("Rejected: ", err));

Promise的方法(多種)

Promise.all()

【01】用于將多個Promise實例,包裝成一個新的Promise實例。
接受一個數組作為參數,數組元素都是Promise實例。
如果參數不是Promise實例,會調用Promise.resolve()轉變為Promise實例。

Promise.all()方法的參數不一定是數組,但是必須具有iterator接口,且返回的每個成員都是Promise實例。

【】返回的新的Promise實例的狀態:

所有Promise參數的都變成Resolved,p的狀態才會變成Resolved,參數的返回值組成一個數組,傳遞給p的回調函數。

只要有一個參數被rejected,p的狀態就變成rejected,此時第一個reject的實例的返回值,會傳遞給p的回調函數。

(小z:類似于且操作,且假或真,只有所有的是成功的才可以。你想想,一系列的操作只有都成功才叫成功。)

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

例子

// 生成一個Promise對象的數組
var promises = [2, 3, 5, 7, 8].map(function(id){return getJSON("/post/" + id + ".json");});

Promise.all(promises).then(function(posts) { // ...
}).catch(function(reason){ // ...
});

Promise.race()
race:賽跑。
【01】將多個Promise實例,包裝成一個新的Promise實例。
返回這個新promise實例,新promise實例的狀態為第一個改變的參數實例的狀態。它的值也是該參數實例傳遞出來的值。

03,參數如果不是Promise實例,就會調用Promise.resolve方法,將參數轉為Promise實例,再進一步處理。

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

例子:

var p = Promise.race([
    fetch("/resource-that-may-take-a-while"),
    new Promise(function (resolve, reject) {
        setTimeout(() => reject(new Error("request timeout")), 5000)
    })])
p.then(response => console.log(response))
p.catch(error => console.log(error))


Promise.reject(reason)

【】會返回一個新的Promise實例,該實例的狀態為rejected。
參數reason,會被傳遞給實例的回調函數。

var p = Promise.reject("出錯了");
// 等同于
var p = new Promise((resolve, reject) => reject("foo"))

p.then(null, function (s){  console.log(s)});// 出錯了




Promise.resolve(obj)

【01】將對象轉為Promise對象。
如果參數不是具有then方法的對象(又稱thenable對象),則返回一個新的Promise對象,且它的狀態為Resolved。
比如:參數為字符串時,不屬于異步操作(判斷方法是它不是具有then方法的對象),所以等價于Promise構造函數立即執行resolve("str");

03,如果沒有參數,可以得到一個Promise對象。
04,如果參數是一個Promise實例,則會被原封不動地返回。

var jsPromise = Promise.resolve($.ajax("/whatever.json"));

Promise.resolve等價于下面的寫法。

Promise.resolve("foo")
// 等價于
new Promise(resolve => resolve("foo"))

例子:

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

例子:

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

Promise.prototype.catch()的概念
【01】是 promise實例.then(null, rejection) 的別名,用于指定發生錯誤時的回調函數。

【】例子:
getJSON方法返回一個Promise對象,如果該對象狀態變為Resolved,則會調用then方法指定的回調函數;
如果異步操作拋出錯誤,狀態就會變為Rejected,就會調用catch方法指定的回調函數,處理這個錯誤。

getJSON("/posts.json").then(function(posts) { // ...
}).catch(function(error) { // 處理前一個回調函數運行時發生的錯誤
    console.log("發生錯誤!", error);
});

例子:

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方法指定的回調函數捕獲。

var promise = new Promise(function(resolve, reject) {
    throw new Error("test") });
promise.catch(function(error) { console.log(error) });// Error: test

盡量不定義then的reject方法
一般來說,不要在then方法里面定義Reject狀態的回調函數(即then的第二個參數),總是使用catch方法。
第二種寫法要好于第一種寫法,理由是前者更接近同步的寫法(try/catch)。

// bad
promise
    .then(function(data) { // success
    }, function(err) { // error
    });
// good
promise
    .then(function(data) { //cb
        // success
    }).catch(function(err) { // error
    });


catch方法返回的還是一個Promise對象,因此后面還可以接著調用then方法。

var someAsyncThing = function() {
return new Promise(function(resolve, reject) { // 下面一行會報錯,因為x沒有聲明
    resolve(x + 2);
});
};
someAsyncThing().catch(function(error) {
    console.log("oh no", error);
}).then(function() {
    console.log("carry on");
});
// oh no [ReferenceError: x is not defined]
// carry on

如果前面的promise和then()沒有報錯,則會跳過catch方法。

Promise.resolve().catch(function(error) {
    console.log("oh no", error);
}).then(function() {
    console.log("carry on");
});
// carry on


拋錯的冒泡性質
Promise對象的錯誤具有“冒泡”性質,會一直向后傳遞,直到被捕獲為止。
也就是說,錯誤總是會被下一個catch語句捕獲。

例子:
一共有三個Promise對象:一個由getJSON產生,兩個由then產生。它們之中任何一個拋出的錯誤,都會被最后一個catch捕獲。

getJSON("/post/1.json").then(function(post) {

return getJSON(post.commentURL); }).then(function(comments) { // some code

}).catch(function(error) { // 處理前面三個Promise產生的錯誤
});

如果Promise狀態已經變成resolved,再拋出錯誤是無效的。
Promise在resolve語句后面,再拋出錯誤,不會被捕獲,等于沒有拋出。

var promise = new Promise(function(resolve, reject) {
resolve("ok");

throw new Error("test"); });

promise.then(function(value) { console.log(value) }).catch(function(error) { console.log(error) });// ok

Promise在下一輪“事件循環”再拋出錯誤
結果由于沒有指定使用try...catch語句,就冒泡到最外層,成了未捕獲的錯誤。
因為此時,Promise的函數體已經運行結束了,所以這個錯誤是在Promise函數體外拋出的。

var promise = new Promise(function(resolve, reject) { 
     resolve("ok");
    setTimeout(function() {
        throw new Error("test") }, 0) });
promise.then(function(value) { console.log(value) });
// ok
// Uncaught Error: test


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

someAsyncThing函數產生的Promise對象會報錯,但是由于沒有指定catch方法,這個錯誤不會被捕獲,也不會傳遞到外層代碼,導致運行后沒有任何輸出。

var someAsyncThing = function() {
    return new Promise(function(resolve, reject) { // 下面一行會報錯,因為x沒有聲明
        resolve(x + 2);
    });
};
someAsyncThing().then(function() {
    console.log("everything is great");
});



catch方法之中,還能再拋出錯誤。
catch方法拋出一個錯誤,因為后面沒有別的catch方法了,導致這個錯誤不會被捕獲,也不會傳遞到外層。

var someAsyncThing = function() {
    return new Promise(function(resolve, reject) { // 下面一行會報錯,因為x沒有聲明
        resolve(x + 2);
    });
};
someAsyncThing().then(function() {
    return someOtherAsyncThing();
 }).catch(function(error) {
    console.log("oh no", error); // 下面一行會報錯,因為y沒有聲明
    y + 2;
}).then(function() {
    console.log("carry on");
});
// oh no [ReferenceError: x is not defined]


如果改寫一下,結果就不一樣了。
第二個catch方法用來捕獲,前一個catch方法拋出的錯誤。

someAsyncThing().then(function() {
    return someOtherAsyncThing(); }).catch(function(error) {
    console.log("oh no", error); // 下面一行會報錯,因為y沒有聲明
    y + 2;
}).catch(function(error) {
    console.log("carry on", error);
});
// oh no [ReferenceError: x is not defined]
// carry on [ReferenceError: y is not defined]



node.js的unhandledRejection
Node.js有一個unhandledRejection事件,專門監聽未捕獲的reject錯誤。
unhandledRejection事件的監聽函數有兩個參數,第一個是錯誤對象,第二個是報錯的Promise實例,它可以用來了解發生錯誤的環境信息。

process.on("unhandledRejection", function (err, p) {
  console.error(err.stack)});




done()

Promise對象的回調鏈,不管以then方法或catch方法結尾,要是最后一個方法拋出錯誤,都有可能會漏掉(Promise內部的錯誤不會冒泡到全局)。
因此,我們可以提供一個done方法,總是處于回調鏈的尾端,保證拋出任何可能出現的錯誤。

asyncFunc().then(f1).catch(r1).then(f2).done();

done方法的使用,可以像then方法那樣用,提供Fulfilled和Rejected狀態的回調函數,也可以不提供任何參數。但不管怎樣,done都會捕捉到任何可能出現的錯誤,并向全局拋出。

實現代碼:

Promise.prototype.done = function (resolve, reject) {
    this.then(resolve, reject).catch(function (reason) { // 拋出一個全局錯誤
        setTimeout(() => {
            throw reason
        }, 0);
    });
};




finally()
finally方法用于指定不管Promise對象最后狀態如何,都會執行的操作。
它與done方法的最大區別,它接受一個普通的回調函數作為參數,該函數不管怎樣都必須執行。

等效于,運行一個then(),在成功和失敗回調函數中,都要運行callback(),
在Promise.resolve()中運行callback()后,在運行then(),返回結果。

下面是一個例子,服務器使用Promise處理請求,然后使用finally方法關掉服務器。

server.listen(0).then(function () { // run test
  }).finally(server.stop);

它的實現:

Promise.prototype.finally = function(callback) {
    return this.then(
        value => Promise.resolve(  callback()  ).then(() => value),
        reason => Promise.resolve(callback()).then(() => {throw reason }));
};







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

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/105517.html

相關文章

  • ES6腳丫系列】遍歷器iterator

    摘要:就稱為部署了遍歷器接口。是一個函數,調用它會生成一個遍歷器對象。它的屬性,也是一個遍歷器對象生成函數,執行后返回它自己。返回遍歷器對象。下面是一個無限運行的遍歷器對象的例子。 『ES6知識點總結』遍歷器iterator本文內容如下: 1 具有iterator接口的數據結構 2 遍歷器過程 3 遍歷器作用: 4 模擬next()方法 5 使用while循環 6 TypeScript的寫法...

    keke 評論0 收藏0
  • ES6腳丫系列】Symbol

    摘要:它是語言的第七種數據類型,前六種是布爾值字符串數值對象。在中,根據屬性名來進行判斷。,是一個布爾值,表示該對象使用時,是否可以展開。等同于,指向該對象的默認遍歷器方法,即該對象進行循環時,會調用這個方法,返回該對象的默認遍歷器。 本文字數:3000+,閱讀時間6分鐘。 如果有理解不到位的地方,歡迎大家糾錯。如果覺得還可以,希望大家可以點個贊。 謝謝大家。 目錄 一、Symbol是什么...

    Flands 評論0 收藏0
  • ES6腳丫系列】箭頭函數

    摘要:箭頭函數本文字符數,閱讀時間約分鐘左右。箭頭函數等于說,只保留了函數的參數和返回。箭頭函數體內的,繼承的是外層代碼塊的。所以,不用用箭頭函數聲明對象的方法。不可以使用命令因此箭頭函數不能用作函數。 【01】ES6箭頭函數 本文字符數4300+,閱讀時間約8分鐘左右。 【01】箭頭函數 等于說,只保留了函數的參數和返回。省略function和return。 寫法: (形參) => {st...

    tinyq 評論0 收藏0
  • ES6腳丫系列】模塊Module

    摘要:命令用于規定本模塊的對外接口。空格模塊名字符串。其他模塊加載該模塊時,命令可以為該匿名函數指定任意名字。寫法函數聲明命令用在非匿名函數前,也是可以的。加載的時候,視同匿名函數加載。 本文字符數8200+,閱讀時間約16分鐘。 『ES6知識點總結』模塊Module 第一節:Module基本概念 【01】過去使用CommonJS和AMD,前者用于服務器,后者用于瀏覽器。 Module可以取...

    gotham 評論0 收藏0
  • ES6腳丫系列】Set+WeakSet+Map+WeakMap

    摘要:返回一個布爾值,表示該值是否為的成員。清除所有成員,沒有返回值。返回的都是遍歷器對象。結構的實例的方法,用于對每個成員執行某種操作,沒有返回值。這個特點意味著,無法引用的成員,因此是不可遍歷的。數組成員是一個或多個表示鍵值對的一維數組。 本文字數:4700+,閱讀時間約10分鐘。 如果有理解不到位的地方,歡迎大家糾錯。 一、Set 【01】Set是一種數據結構。類似于數組,但是成員的值...

    lyning 評論0 收藏0

發表評論

0條評論

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