目錄
- 一.什么是Promise:
- 二.為啥使用Promise:
- 三. promise初體驗:
- 四:promise體驗ajax請求:
- 五:Promise封裝ajax請求:
- 六:promise的狀態改變:
- 七:Promise基本流程圖:
- 八:Promise的API 使用:
- 1. Promise 的建構式:Promise(executor){}
- 2. Promise.prototype.then 方法: (onResolved, onRejected)=> {}
- 3.Promise.prototype.catch萬法: (onRejected) => {}
- 4. Promise.resolve 方法: (value)=> {}
- 5. Promise.reject 方法: (reason) => {}
- 6. Promise.all 方法: (promises)=> {}
- 7. Promise.race 方法: (promises)=> {}
- 九:使用Promise面臨的關鍵問題:
- 1.如何改變 promise的狀態?
- 2.一個 promise指定多個成功/失敗回呼函式,都會呼叫嗎?
- 4. promise.then()回傳的新promise的結果狀態由什么決定?
- 5. promise 如何串連多個操作任務?
- 6. promise 的例外穿透,
- 7.中斷 promise鏈,
- 十:Promise的自定義封裝:
- 1.初始化結構搭建:
- 2. 搭建resolve與reject結構:
- 3. 實作resolve與reject函式:
- 4. throw拋出例外改變狀態:
- 5. 設定Promise物件狀態只能修改一次:
- 6. then()方法執行回呼:
- 7.執行異步任務回呼:
- 8.能執行多個回呼:
- 9.同步任務 then()的回傳結果:
- 10.異步任務 then()的回傳結果:
- 11. 完善then()方法與優化:
- 12. 實作catch方法與例外穿透:
- 13. 封裝Promise.resolve()方法:
- 14. 封裝Promise.reject方法:
- 15. 封裝Promise.all方法:
- 16. 封裝Promise.race方法:
- 17.回呼函式異步執行:
- 18.class版本封裝:
- 十一:async函式:
- 1.回傳一個非Promise物件,回傳值是resolve,
- 2.如果回傳是一個Promise物件,由回傳結果決定:
- 3.拋出例外也是失敗:
- 十二.await運算式:
- 1.右側為promise物件:
- 2.右側為其它值:
- 3.如果promise是失敗狀態:
- 十三.async與await結合發生ajax請求:
- 十四.總結:
一.什么是Promise:
- Promise 是在 js 中進行異步編程的新解決方案,(以前舊的方案是單純使用回呼函式)
- 從語法來說,promise是一個建構式,
- 從功能來說,promise物件用來封裝一個異步操作,并且可以獲得成功或失敗的回傳值,
- JS中的常見的異步操作:定時器,AJAX中一般也是異步操作(也可以同步),回呼函式可以理解為異步(不是嚴謹的異步操作)…等,
剩下的都是同步處理
二.為啥使用Promise:
- promise使用回呼函式更靈活,舊的回呼函式必須在啟動異步任務前指定,
- promise:啟動異步任務 => 回傳promise物件 => 給promise物件系結回呼函式(甚至能在異步任務結束后指定多個)
- promise支持鏈式呼叫,可以解決回呼地獄問題,(回呼地獄就是多層回呼函式嵌套使用,就是套娃,這樣就不利于閱讀和例外處理,)
三. promise初體驗:
效果:點擊一個按鈕,有30%概率顯示中獎,
實作: 點擊按鈕后得到一個1到100間的亂數,小于等于30輸出中獎,否則輸出沒中,期間用定時器模擬異步操作,在定時器里執行判斷,
(1)基礎的寫法:
<button id="btn">click</button>
<script>
var btn = document.querySelector("#btn");
// 該函式回傳一個兩數之間的隨機整數,包括兩個數在內
function getRandomIntInclusive(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min + 1)) + min; //含最大值,含最小值
}
// 點擊事件
btn.addEventListener('click',function(){
// 1秒的定時器,模擬異步操作
setTimeout(() => {
// 得到1到100間的一個數
let n = getRandomIntInclusive(1, 100);
if (n <= 30) {
alert('中獎嘍');
} else {
alert('沒中獎');
}
}, 1000);
})
</script>

(2)promise寫法,在promise里封裝一個異步操作,
<script>
var btn = document.querySelector("#btn");
// 得到一個兩數之間的隨機整數,包括兩個數在內
function getRandomIntInclusive(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min + 1)) + min; //含最大值,含最小值
}
// 點擊事件
btn.addEventListener('click',function(){
// 下面是promise ,resolve表示解決,reject表示拒絕 ,都是函式型別資料,
const p = new Promise((resolve,reject) => {
setTimeout(()=>{
let n = getRandomIntInclusive(1, 100);
if(n<=30){
resolve(); //將promise狀態設為 “成功”
}else{
reject(); //將promise狀態設為 “失敗”
}
},1000)
});
// 呼叫then方法
p.then(()=>{
// “成功”執行這步
alert('中獎嘍');
},()=>{
// “失敗”執行這步
alert('沒中獎');
})
})
假如要在上面輸出結果后加上選中的號碼:
因為.then()里并不能直接獲得 n,所以在resolve與reject里把n當結果值回傳,
// 點擊事件
btn.addEventListener('click',function(){
// 下面是promise ,resolve表示解決,reject表示拒絕 ,都是函式型別資料,
const p = new Promise((resolve,reject) => {
setTimeout(()=>{
let n = getRandomIntInclusive(1, 100);
if(n<=30){
resolve(n); //將promise狀態設為 “成功”,并把結果值n回傳
}else{
reject(n); //將promise狀態設為 “失敗”,并把結果值n回傳
}
},1000)
});
// 呼叫then方法
// value為值的意思,reason為理由的意思,都是形參
p.then((value)=>{
// “成功”執行
alert('中獎嘍'+value);
},(reason)=>{
// “失敗”執行
alert('沒中獎'+reason);
})
})

四:promise體驗ajax請求:
這是一個開源社區的api檔案,有許多api,
效果:點擊按鈕獲得一句名言在控制臺輸出,
基礎寫法:
<script>
var btn = document.querySelector("#btn");
// 點擊事件
btn.addEventListener('click',function(){
//創建物件
const xhr = new XMLHttpRequest();
//初始化
xhr.open('GET',"http://poetry.apiopen.top/sentences");
//發送
xhr.send();
//處理回應結果
xhr.onreadystatechange = function(){
if(xhr.readyState === 4){
if(xhr.status >=200 && xhr.status < 300){
//輸出回應體
console.log(xhr.response);
}else{
//輸出回應狀態碼
console.log(xhr.status);
}
}
}
})
</script>

promise封裝:
// 點擊事件
btn.addEventListener('click',function(){
const p = new Promise((resolve,reject) => {
//創建物件
const xhr = new XMLHttpRequest();
//初始化
xhr.open('GET', "http://poetry.apiopen.top/sentences");
//發送
xhr.send();
//處理回應結果
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status >= 200 && xhr.status < 300) {
//輸出回應體
resolve(xhr.response);
} else {
//輸出回應狀態碼
reject(xhr.status);
}
}
}
})
p.then(value=>{
console.log(value);
},reason=>{
//控制臺輸出警告資訊
console.warn(reason);
})
})

若把介面寫錯:

五:Promise封裝ajax請求:
跟上一步差不多,就是把其封裝在一個sendAJAX()的自定義函式里,
function sendAJAX(url) {
return new Promise((resolve, reject) => {
//創建物件
const xhr = new XMLHttpRequest();
xhr.responseType = 'json';
//初始化
xhr.open('GET', url);
//發送
xhr.send();
//處理回應結果
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status >= 200 && xhr.status < 300) {
//輸出回應體
resolve(xhr.response);
} else {
//輸出回應狀態碼
reject(xhr.status);
}
}
}
});
}
sendAJAX("http://poetry.apiopen.top/sentences")
.then(value=>{
console.log(value);
},reason=>{
//控制臺輸出警告資訊
console.warn(reason);
})
六:promise的狀態改變:
promise狀態表示實體物件的一個屬性【PromiseState】,包括以下值:
(1)pending 未決定的
(2)resolved 或 fullfilled 成功
(3)rejected 失敗
Promise物件的值表示實體物件的另一個屬性【PromiseResult】,保存著物件【成功/失敗】的結果,而其狀態改變只有以下兩種可能:
(1)pending 變為resolved
(2)pending 變為 rejected
注:一個promise物件只能改變一次,無論成功或失敗都會有一個結果資料,成功的稱為 value , 失敗的稱為 reason ,
七:Promise基本流程圖:

八:Promise的API 使用:
1. Promise 的建構式:Promise(executor){}
(1)executor 函式:執行器 (resolve,reject)=> {},
(2)resolve 函式:內部定義成功時呼叫函式 value => {} ,
(3)reject 函式:內部定義失敗時呼叫函式 reason => {} ,
注意:Promise內部會立同步即呼叫executor,異步操作在執行器里執行,
2. Promise.prototype.then 方法: (onResolved, onRejected)=> {}
(1) onResolved 函式:成功的回呼函式 (value) => {}
(2) onRejected 函式:失敗的回呼函式 (reason) => {}
注:指定用于得到成功value的成功回呼和用于得到失敗reason的失敗回呼是回傳一個新的promise物件,
3.Promise.prototype.catch萬法: (onRejected) => {}
onRejected.函式: 失敗的回呼函式**(reason)=> {}**
注:只是失敗的呼叫,then()的語法糖,相當于: then(undefined, onRejected),
4. Promise.resolve 方法: (value)=> {}
value: 成功的資料或promise物件
注:如果傳入的引數為非Promise類 型的物件,則回傳的結果為成功promise物件,如果傳入的引數為Promise 物件,則引數的結果決定了resolve 的結果,
5. Promise.reject 方法: (reason) => {}
reason: 失敗的原因
注:無論傳入啥只回傳一個失敗的promise物件,
6. Promise.all 方法: (promises)=> {}
promises: 包含n個promise的陣列
注:回傳一個新的promise,只有所有的promise都成功才成功,只要有一個失敗了就直接失敗,失敗了回傳那個失敗值,
7. Promise.race 方法: (promises)=> {}
promises: 包含n個promise的陣列
注:回傳一個新的promise,第一個完成的promise的結果狀態就是最終的結果狀態,
來一個例子:
let p1 = new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve('yes');
},1000)
})
let p2 = Promise.resolve('success');
let p3 = Promise.resolve('come');
const result = Promise.race([p1,p2,p3]);
console.log(result);

九:使用Promise面臨的關鍵問題:
1.如何改變 promise的狀態?
(1) resolve(value): 如果當前是pending就會變為resolved,
(2) reject(reason): 如果當前是pending就會變為rejected,
(3)拋出例外 throw :如果當前是pending就會變為rejected,
let p1 = new Promise((resolve,reject)=>{
// resolve('success');
// reject('error');
// throw 'error';
})
2.一個 promise指定多個成功/失敗回呼函式,都會呼叫嗎?
當promise改變為對應狀態時都會呼叫,
let p = new Promise((resolve,reject)=>{
resolve('success');
})
// 第一次回呼
p.then(value=>{
console.log("yes");
})
// 第二次回呼
p.then(value=>{
console.log("oh yes");
})

3.改變 promiseT狀態和指定回呼函式誰先誰后?
(1)都有可能, 正常情況下是先指定回呼再改變狀態,但也可以先改狀態再指定回呼
(2)如何先改狀態再指定回呼?
①在執行 器中直接呼叫resolve(/reject();
②延遲更 長時間才呼叫then();
(3)什么時候才能得到資料?
①如果先指定的回呼, 那當狀態發生改變時,回呼函式就會呼叫,得到資料
②如果先改變的狀態, 那當指定回呼時,回呼函式就會呼叫,得到資料
4. promise.then()回傳的新promise的結果狀態由什么決定?
(1)簡單表達: then()指定的回呼函式執行的結果決定,
(2)詳細表達:
*如果拋出例外, 新promise變為rejected, reaon為拋出的例外,
*如果回傳的是非prormise的任意值,新promise變為resolved, value為回傳的值,
*如果回傳的是另一個新promise,此promise的結果就會成為新promise的結果,
隨筆:
let p = new Promise((resolve,reject) => {
// resolve('success');
// reject('No');
// throw 'oh no';
});
let result = p.then(value => {
console.log(value);
}, reason => {
console.warn(reason);
});
console.log(result);
5. promise 如何串連多個操作任務?
(1) promise 的then()回傳一個新的promise,可以開成then()的鏈式呼叫,
(2)通過then的鏈式呼叫串連多個同步/異步任務,
let p =new Promise((resolve,reject) => {
resolve("yes");
})
p.then(value => {
return new Promise((resolve,reject)=>{
resolve("oh yes~");
});
}).then(value => {
console.log(value);
})
輸出結果:
oh yes~
let p =new Promise((resolve,reject) => {
resolve("yes");
})
p.then(value => {
return new Promise((resolve,reject)=>{
resolve("oh yes~");
});
}).then(value => {
console.log(value);
}).then(value => {
console.log(value);
})
輸出結果:
oh yes~
undefined
6. promise 的例外穿透,
(1)當使用promise的then鏈式呼叫時,可以在最后指定失敗的回呼,
(2)前面任何操作出 了例外,都會傳到最后失敗的回呼中處理,
let p =new Promise((resolve,reject) => {
setTimeout(()=>{
resolve("yes");
},1000);
})
p.then(value => {
throw 'oh No';
}).then(value => {
console.log("123");
}).then(value => {
console.log("456");
}).catch(reason=>{
console.warn(reason);
})
輸出結果:
oh No
7.中斷 promise鏈,
(1)當使用promise的then鏈式呼叫時,在中間中斷,不再呼叫后面的回呼函式,
(2)辦法:在回呼函式中回傳一個pendding狀態的promise物件,
未中斷:
let p =new Promise((resolve,reject) => {
setTimeout(()=>{
resolve("yes");
},1000);
})
p.then(value => {
console.log("789");
}).then(value => {
console.log("123");
}).then(value => {
console.log("456");
}).catch(reason=>{
console.warn(reason);
})
輸出結果:
789
123
456
中斷:
let p =new Promise((resolve,reject) => {
setTimeout(()=>{
resolve("yes");
},1000);
})
p.then(value => {
console.log("789");
return new Promise(()=>{});
}).then(value => {
console.log("123");
}).then(value => {
console.log("456");
}).catch(reason=>{
console.warn(reason);
})
輸出結果:
789
十:Promise的自定義封裝:
1.初始化結構搭建:
// 自定義函式 Promise
function Promise(executor){
}
// 添加then方法
Promise.prototype.then = function(onResolved,onRejected){
}
注:prototype 屬性使您有能力向物件添加屬性和方法,
2. 搭建resolve與reject結構:
// 自定義函式Promise
function Promise(executor){
//自定義resolve函式,名字不一定用resolve
function resolve(data){
}
//自定義reject函式
function reject(data){
}
//同步呼叫【執行器函式】
executor(resolve,reject);
}
// 添加then方法
Promise.prototype.then = function(onResolved,onRejected){
}
3. 實作resolve與reject函式:
// 自定義函式Promise
function Promise(executor){
//添加狀態屬性與結果值屬性
this.PromiseState = 'pending';
this.PromiseResult = null;
//保存實體物件的this值
const that = this;
//自定義resolve函式,名字不一定用resolve
function resolve(data){
//改變狀態屬性
that.PromiseState = 'fulfilled'; // 或者 resolved
//改變結果值屬性
that.PromiseResult =data;
}
//自定義reject函式
function reject(data){
//改變狀態屬性
that.PromiseState = 'rejected';
//改變結果值屬性
that.PromiseResult =data;
}
//同步呼叫【執行器函式】
executor(resolve,reject);
}
// 添加then方法
Promise.prototype.then = function(onResolved,onRejected){
}
4. throw拋出例外改變狀態:
采用 try{ }catch(){ } 與throw一起使用,
// 自定義函式Promise
function Promise(executor){
//添加狀態屬性與結果值屬性
this.PromiseState = 'pending';
this.PromiseResult = null;
//保存實體物件的this值
const that = this;
//自定義resolve函式,名字不一定用resolve
function resolve(data){
//改變狀態屬性
that.PromiseState = 'fulfilled'; // 或者 resolve
//改變結果值屬性
that.PromiseResult =data;
}
//自定義reject函式
function reject(data){
//改變狀態屬性
that.PromiseState = 'rejected';
//改變結果值屬性
that.PromiseResult =data;
}
try{
//同步呼叫【執行器函式】
executor(resolve,reject);
}catch(e){
//更改Promise物件為失敗
reject(e);
}
}
// 添加then方法
Promise.prototype.then = function(onResolved,onRejected){
}
注:throw陳述句拋出一個錯誤,
5. 設定Promise物件狀態只能修改一次:
加個判斷就好,
// 自定義函式Promise
function Promise(executor){
//添加狀態屬性與結果值屬性
this.PromiseState = 'pending';
this.PromiseResult = null;
//保存實體物件的this值
const that = this;
//自定義resolve函式,名字不一定用resolve
function resolve(data){
//判斷狀態是否修改過,改過就直接回傳
if(that.PromiseState !== 'pending') return;
//改變狀態屬性
that.PromiseState = 'fulfilled'; // 或者 resolve
//改變結果值屬性
that.PromiseResult =data;
}
//自定義reject函式
function reject(data){
//判斷狀態是否修改過,改過就直接回傳
if(that.PromiseState !== 'pending') return;
//改變狀態屬性
that.PromiseState = 'rejected';
//改變結果值屬性
that.PromiseResult =data;
}
try{
//同步呼叫【執行器函式】
executor(resolve,reject);
}catch(e){
//更改Promise物件為失敗
reject(e);
}
}
// 添加then方法
Promise.prototype.then = function(onResolved,onRejected){
}
6. then()方法執行回呼:
// 自定義函式Promise
function Promise(executor){
//添加狀態屬性與結果值屬性
this.PromiseState = 'pending';
this.PromiseResult = null;
//保存實體物件的this值
const that = this;
//自定義resolve函式,名字不一定用resolve
function resolve(data){
//判斷狀態是否修改過
if(that.PromiseState !== 'pending') return;
//改變狀態屬性
that.PromiseState = 'fulfilled'; // 或者 resolve
//改變結果值屬性
that.PromiseResult =data;
}
//自定義reject函式
function reject(data){
//判斷狀態是否修改過,改過就直接回傳
if(that.PromiseState !== 'pending') return;
//改變狀態屬性
that.PromiseState = 'rejected';
//改變結果值屬性
that.PromiseResult =data;
}
try{
//同步呼叫【執行器函式】
executor(resolve,reject);
}catch(e){
//更改Promise物件為失敗
reject(e);
}
}
// 添加then方法
Promise.prototype.then = function(onResolved,onRejected){
//如果Promise狀態為fulfilled回呼這個函式
if(this.PromiseState === 'fulfilled'){
//將結果值傳入
onResolved(this.PromiseResult);
}
//如果Promise狀態為rejected回呼這個函式
if(this.PromiseState === 'rejected'){
//將結果值傳入
onRejected(this.PromiseResult);
}
}
7.執行異步任務回呼:
異步任務一般先回呼才改變狀態,所以第6步的代碼執行順序就無法執行異步回呼,解決如下:
// 自定義函式Promise
function Promise(executor){
//添加狀態屬性與結果值屬性
this.PromiseState = 'pending';
this.PromiseResult = null;
// 定義callback屬性,保存pending狀態的回呼函式
this.callback = {};
//保存實體物件的this值
const that = this;
//自定義resolve函式,名字不一定用resolve
function resolve(data){
//判斷狀態是否修改過
if(that.PromiseState !== 'pending') return;
//改變狀態屬性
that.PromiseState = 'fulfilled'; // 或者 resolve
//改變結果值屬性
that.PromiseResult =data;
//異步任務成功后執行回呼函式
if(that.callback.onResolved){
that.callback.onResolved(data);
}
}
//自定義reject函式
function reject(data){
//判斷狀態是否修改過,改過就直接回傳
if(that.PromiseState !== 'pending') return;
//改變狀態屬性
that.PromiseState = 'rejected';
//改變結果值屬性
that.PromiseResult =data;
//異步任務失敗后執行回呼函式
if(that.callback.onRejected){
that.callback.onRejected(data);
}
}
try{
//同步呼叫【執行器函式】
executor(resolve,reject);
}catch(e){
//更改Promise物件為失敗
reject(e);
}
}
// 添加then方法
Promise.prototype.then = function(onResolved,onRejected){
//如果Promise狀態為fulfilled回呼這個函式
if(this.PromiseState === 'fulfilled'){
//將結果值傳入
onResolved(this.PromiseResult);
}
//如果Promise狀態為rejected回呼這個函式
if(this.PromiseState === 'rejected'){
//將結果值傳入
onRejected(this.PromiseResult);
}
//如果Promise狀態為pending,保存回呼函式
if(this.PromiseState === 'pending'){
this.callback = {
onResolved: onResolved,
onRejected: onRejected
}
}
}
8.能執行多個回呼:
用第7步寫法指定多個回呼時,最后一個then回呼會覆寫掉前面的,解決如下,把保存回呼函式的callbacks變為一個陣列:
// 自定義函式Promise
function Promise(executor){
//添加狀態屬性與結果值屬性
this.PromiseState = 'pending';
this.PromiseResult = null;
// 定義callback屬性,保存pending狀態的回呼函式
this.callbacks = [];
//保存實體物件的this值
const that = this;
//自定義resolve函式,名字不一定用resolve
function resolve(data){
//判斷狀態是否修改過
if(that.PromiseState !== 'pending') return;
//改變狀態屬性
that.PromiseState = 'fulfilled'; // 或者 resolve
//改變結果值屬性
that.PromiseResult =data;
//異步任務成功后執行回呼函式
that.callbacks.forEach(item=>{
item.onResolved(data);
})
}
//自定義reject函式
function reject(data){
//判斷狀態是否修改過,改過就直接回傳
if(that.PromiseState !== 'pending') return;
//改變狀態屬性
that.PromiseState = 'rejected';
//改變結果值屬性
that.PromiseResult =data;
//異步任務失敗后執行回呼函式
that.callbacks.forEach(item=>{
item.onRejected(data);
})
}
try{
//同步呼叫【執行器函式】
executor(resolve,reject);
}catch(e){
//更改Promise物件為失敗
reject(e);
}
}
// 添加then方法
Promise.prototype.then = function(onResolved,onRejected){
//如果Promise狀態為fulfilled回呼這個函式
if(this.PromiseState === 'fulfilled'){
//將結果值傳入
onResolved(this.PromiseResult);
}
//如果Promise狀態為rejected回呼這個函式
if(this.PromiseState === 'rejected'){
//將結果值傳入
onRejected(this.PromiseResult);
}
//如果Promise狀態為pending,保存回呼函式
if(this.PromiseState === 'pending'){
this.callbacks.push({
onResolved: onResolved,
onRejected: onRejected
})
}
}
forEach()方法
9.同步任務 then()的回傳結果:
就是在then()里有實作有結果回傳:
const result = p.then(value => {
console.log(value);
},reason => {
console.warn(reason);
})
console.log(result);
解決:
// 自定義函式Promise
function Promise(executor){
//添加狀態屬性與結果值屬性
this.PromiseState = 'pending';
this.PromiseResult = null;
// 定義callback屬性,保存pending狀態的回呼函式
this.callbacks = [];
//保存實體物件的this值
const that = this;
//自定義resolve函式,名字不一定用resolve
function resolve(data){
//判斷狀態是否修改過
if(that.PromiseState !== 'pending') return;
//改變狀態屬性
that.PromiseState = 'fulfilled'; // 或者 resolve
//改變結果值屬性
that.PromiseResult =data;
//異步任務成功后執行回呼函式
that.callbacks.forEach(item=>{
item.onResolved(data);
})
}
//自定義reject函式
function reject(data){
//判斷狀態是否修改過,改過就直接回傳
if(that.PromiseState !== 'pending') return;
//改變狀態屬性
that.PromiseState = 'rejected';
//改變結果值屬性
that.PromiseResult =data;
//異步任務失敗后執行回呼函式
that.callbacks.forEach(item=>{
item.onRejected(data);
})
}
try{
//同步呼叫【執行器函式】
executor(resolve,reject);
}catch(e){
//更改Promise物件為失敗
reject(e);
}
}
// 添加then方法
Promise.prototype.then = function (onResolved, onRejected) {
return new Promise((resolve, reject) => {
//如果Promise狀態為fulfilled回呼這個函式
if (this.PromiseState === 'fulfilled') {
try {
//獲取回呼函式執行結果
let result = onResolved(this.PromiseResult);
//判斷
if (result instanceof Promise) {
//如果是Promise物件
result.then(v => {
resolve(v);
}, r => {
reject(r);
})
} else {
//結果物件狀態為【成功】
resolve(result);
}
} catch (e) {
reject(e);
}
}
//如果Promise狀態為rejected回呼這個函式
if (this.PromiseState === 'rejected') {
//將結果值傳入
onRejected(this.PromiseResult);
}
//如果Promise狀態為pending,保存回呼函式
if (this.PromiseState === 'pending') {
this.callbacks.push({
onResolved: onResolved,
onRejected: onRejected
})
}
})
}
注:instanceof 運算子用于檢測建構式的 prototype 屬性是否出現在某個實體物件的原型鏈上,
10.異步任務 then()的回傳結果:
(′?`」 ∠)
用第9步執行異步任務return回傳的會是pending狀態,
解決:
// 自定義函式Promise
function Promise(executor){
//添加狀態屬性與結果值屬性
this.PromiseState = 'pending';
this.PromiseResult = null;
// 定義callback屬性,保存pending狀態的回呼函式
this.callbacks = [];
//保存實體物件的this值
const that = this;
//自定義resolve函式,名字不一定用resolve
function resolve(data){
//判斷狀態是否修改過
if(that.PromiseState !== 'pending') return;
//改變狀態屬性
that.PromiseState = 'fulfilled'; // 或者 resolve
//改變結果值屬性
that.PromiseResult =data;
//異步任務成功后執行回呼函式
that.callbacks.forEach(item=>{
item.onResolved(data);
})
}
//自定義reject函式
function reject(data){
//判斷狀態是否修改過,改過就直接回傳
if(that.PromiseState !== 'pending') return;
//改變狀態屬性
that.PromiseState = 'rejected';
//改變結果值屬性
that.PromiseResult =data;
//異步任務失敗后執行回呼函式
that.callbacks.forEach(item=>{
item.onRejected(data);
})
}
try{
//同步呼叫【執行器函式】
executor(resolve,reject);
}catch(e){
//更改Promise物件為失敗
reject(e);
}
}
// 添加then方法
Promise.prototype.then = function (onResolved, onRejected) {
const that = this;
return new Promise((resolve, reject) => {
//如果Promise狀態為fulfilled回呼這個函式
if (this.PromiseState === 'fulfilled') {
try {
//將結果值傳入
let result = onResolved(this.PromiseResult);
//判斷
if (result instanceof Promise) {
//如果是Promise物件
result.then(v => {
resolve(v);
}, r => {
reject(r);
})
} else {
//結果物件狀態為【成功】
resolve(result);
}
} catch (e) {
reject(e);
}
}
//如果Promise狀態為rejected回呼這個函式
if (this.PromiseState === 'rejected') {
//將結果值傳入
onRejected(this.PromiseResult);
}
//如果Promise狀態為pending,保存回呼函式
if (this.PromiseState === 'pending') {
this.callbacks.push({
onResolved: function () {
try {
//執行成功回呼函式
let result = onResolved(that.PromiseResult);
//判斷
if (result instanceof Promise) {
result.then(v => {
resolve(v);
}, r => {
reject(r);
})
} else {
resolve(result);
}
} catch (e) {
reject(e);
}
},
onRejected: function () {
try {
//執行成功回呼函式
let result = onRejected(that.PromiseResult);
//判斷
if (result instanceof Promise) {
result.then(v => {
resolve(v);
}, r => {
reject(r);
})
} else {
resolve(result);
}
} catch(e){
reject(e);
}
}
})
}
})
}
11. 完善then()方法與優化:
// 自定義函式Promise
function Promise(executor){
//添加狀態屬性與結果值屬性
this.PromiseState = 'pending';
this.PromiseResult = null;
// 定義callback屬性,保存pending狀態的回呼函式
this.callbacks = [];
//保存實體物件的this值
const that = this;
//自定義resolve函式,名字不一定用resolve
function resolve(data){
//判斷狀態是否修改過
if(that.PromiseState !== 'pending') return;
//改變狀態屬性
that.PromiseState = 'fulfilled'; // 或者 resolve
//改變結果值屬性
that.PromiseResult =data;
//異步任務成功后執行回呼函式
that.callbacks.forEach(item=>{
item.onResolved(data);
})
}
//自定義reject函式
function reject(data){
//判斷狀態是否修改過,改過就直接回傳
if(that.PromiseState !== 'pending') return;
//改變狀態屬性
that.PromiseState = 'rejected';
//改變結果值屬性
that.PromiseResult =data;
//異步任務失敗后執行回呼函式
that.callbacks.forEach(item=>{
item.onRejected(data);
})
}
try{
//同步呼叫【執行器函式】
executor(resolve,reject);
}catch(e){
//更改Promise物件為失敗
reject(e);
}
}
// 添加then方法
Promise.prototype.then = function (onResolved, onRejected) {
const that = this;
return new Promise((resolve, reject) => {
//封裝重復的部分
function callback(type){
try {
//將結果值傳入
let result = type(that.PromiseResult);
//判斷
if (result instanceof Promise) {
//如果是Promise物件
result.then(v => {
resolve(v);
}, r => {
reject(r);
})
} else {
//結果物件狀態為【成功】
resolve(result);
}
} catch (e) {
reject(e);
}
}
//如果Promise狀態為fulfilled回呼這個函式
if (this.PromiseState === 'fulfilled') {
callback(onResolved);
}
//如果Promise狀態為rejected回呼這個函式
if (this.PromiseState === 'rejected') {
callback(onRejected);
}
//如果Promise狀態為pending,保存回呼函式
if (this.PromiseState === 'pending') {
this.callbacks.push({
onResolved: function () {
callback(onResolved);
},
onRejected: function () {
callback(onRejected);
}
})
}
})
}
12. 實作catch方法與例外穿透:
// 自定義函式Promise
function Promise(executor){
//添加狀態屬性與結果值屬性
this.PromiseState = 'pending';
this.PromiseResult = null;
// 定義callback屬性,保存pending狀態的回呼函式
this.callbacks = [];
//保存實體物件的this值
const that = this;
//自定義resolve函式,名字不一定用resolve
function resolve(data){
//判斷狀態是否修改過
if(that.PromiseState !== 'pending') return;
//改變狀態屬性
that.PromiseState = 'fulfilled'; // 或者 resolve
//改變結果值屬性
that.PromiseResult =data;
//異步任務成功后執行回呼函式
that.callbacks.forEach(item=>{
item.onResolved(data);
})
}
//自定義reject函式
function reject(data){
//判斷狀態是否修改過,改過就直接回傳
if(that.PromiseState !== 'pending') return;
//改變狀態屬性
that.PromiseState = 'rejected';
//改變結果值屬性
that.PromiseResult =data;
//異步任務失敗后執行回呼函式
that.callbacks.forEach(item=>{
item.onRejected(data);
})
}
try{
//同步呼叫【執行器函式】
executor(resolve,reject);
}catch(e){
//更改Promise物件為失敗
reject(e);
}
}
// 添加then方法
Promise.prototype.then = function (onResolved, onRejected) {
const that = this;
//判斷回呼引數是否存在
if(typeof onRejected !== 'function'){
onRejected = reason =>{
throw reason;
}
}
if(typeof onResolved !== 'function'){
onResolved = value => value;
}
return new Promise((resolve, reject) => {
//封裝重復的部分
function callback(type){
try {
//將結果值傳入
let result = type(that.PromiseResult);
//判斷
if (result instanceof Promise) {
//如果是Promise物件
result.then(v => {
resolve(v);
}, r => {
reject(r);
})
} else {
//結果物件狀態為【成功】
resolve(result);
}
} catch (e) {
reject(e);
}
}
//如果Promise狀態為fulfilled回呼這個函式
if (this.PromiseState === 'fulfilled') {
callback(onResolved);
}
//如果Promise狀態為rejected回呼這個函式
if (this.PromiseState === 'rejected') {
callback(onRejected);
}
//如果Promise狀態為pending,保存回呼函式
if (this.PromiseState === 'pending') {
this.callbacks.push({
onResolved: function () {
callback(onResolved);
},
onRejected: function () {
callback(onRejected);
}
})
}
})
}
//添加catch 方法
Promise.prototype.catch = function(onRejected){
return this.then(undefined,onRejected);
}
注:typeof 運算子回傳一個字串,表示未經計算的運算元的型別,
13. 封裝Promise.resolve()方法:
// 自定義函式Promise
function Promise(executor){
//添加狀態屬性與結果值屬性
this.PromiseState = 'pending';
this.PromiseResult = null;
// 定義callback屬性,保存pending狀態的回呼函式
this.callbacks = [];
//保存實體物件的this值
const that = this;
//自定義resolve函式,名字不一定用resolve
function resolve(data){
//判斷狀態是否修改過
if(that.PromiseState !== 'pending') return;
//改變狀態屬性
that.PromiseState = 'fulfilled'; // 或者 resolve
//改變結果值屬性
that.PromiseResult =data;
//異步任務成功后執行回呼函式
that.callbacks.forEach(item=>{
item.onResolved(data);
})
}
//自定義reject函式
function reject(data){
//判斷狀態是否修改過,改過就直接回傳
if(that.PromiseState !== 'pending') return;
//改變狀態屬性
that.PromiseState = 'rejected';
//改變結果值屬性
that.PromiseResult =data;
//異步任務失敗后執行回呼函式
that.callbacks.forEach(item=>{
item.onRejected(data);
})
}
try{
//同步呼叫【執行器函式】
executor(resolve,reject);
}catch(e){
//更改Promise物件為失敗
reject(e);
}
}
// 添加then方法
Promise.prototype.then = function (onResolved, onRejected) {
const that = this;
//判斷回呼引數是否存在
if(typeof onRejected !== 'function'){
onRejected = reason =>{
throw reason;
}
}
if(typeof onResolved !== 'function'){
onResolved = value => value;
}
return new Promise((resolve, reject) => {
//封裝重復的部分
function callback(type){
try {
//將結果值傳入
let result = type(that.PromiseResult);
//判斷
if (result instanceof Promise) {
//如果是Promise物件
result.then(v => {
resolve(v);
}, r => {
reject(r);
})
} else {
//結果物件狀態為【成功】
resolve(result);
}
} catch (e) {
reject(e);
}
}
//如果Promise狀態為fulfilled回呼這個函式
if (this.PromiseState === 'fulfilled') {
callback(onResolved);
}
//如果Promise狀態為rejected回呼這個函式
if (this.PromiseState === 'rejected') {
callback(onRejected);
}
//如果Promise狀態為pending,保存回呼函式
if (this.PromiseState === 'pending') {
this.callbacks.push({
onResolved: function () {
callback(onResolved);
},
onRejected: function () {
callback(onRejected);
}
})
}
})
}
//添加catch 方法
Promise.prototype.catch = function(onRejected){
return this.then(undefined,onRejected);
}
//添加resolve方法
Promise.resolve = function(value){
//回傳promise物件
return new Promise((resolve,reject) =>{
if(value instanceof Promise){
value.then(v=>{
resolve(v);
},r=>{
reject(r);
})
}else{
resolve(value);
}
})
}
注:instanceof 運算子用于檢測建構式的 prototype 屬性是否出現在某個實體物件的原型鏈上,
實踐一下:
let p = Promise.resolve(new Promise((resolve,reject)=>{
reject('_(′?`」 ∠)_');
}));
console.log(p);
結果:

14. 封裝Promise.reject方法:
無論傳入啥只回傳一個失敗的promise物件,
// 自定義函式Promise
function Promise(executor){
//添加狀態屬性與結果值屬性
this.PromiseState = 'pending';
this.PromiseResult = null;
// 定義callback屬性,保存pending狀態的回呼函式
this.callbacks = [];
//保存實體物件的this值
const that = this;
//自定義resolve函式,名字不一定用resolve
function resolve(data){
//判斷狀態是否修改過
if(that.PromiseState !== 'pending') return;
//改變狀態屬性
that.PromiseState = 'fulfilled'; // 或者 resolve
//改變結果值屬性
that.PromiseResult =data;
//異步任務成功后執行回呼函式
that.callbacks.forEach(item=>{
item.onResolved(data);
})
}
//自定義reject函式
function reject(data){
//判斷狀態是否修改過,改過就直接回傳
if(that.PromiseState !== 'pending') return;
//改變狀態屬性
that.PromiseState = 'rejected';
//改變結果值屬性
that.PromiseResult =data;
//異步任務失敗后執行回呼函式
that.callbacks.forEach(item=>{
item.onRejected(data);
})
}
try{
//同步呼叫【執行器函式】
executor(resolve,reject);
}catch(e){
//更改Promise物件為失敗
reject(e);
}
}
// 添加then方法
Promise.prototype.then = function (onResolved, onRejected) {
const that = this;
//判斷回呼引數是否存在
if(typeof onRejected !== 'function'){
onRejected = reason =>{
throw reason;
}
}
if(typeof onResolved !== 'function'){
onResolved = value => value;
}
return new Promise((resolve, reject) => {
//封裝重復的部分
function callback(type){
try {
//將結果值傳入
let result = type(that.PromiseResult);
//判斷
if (result instanceof Promise) {
//如果是Promise物件
result.then(v => {
resolve(v);
}, r => {
reject(r);
})
} else {
//結果物件狀態為【成功】
resolve(result);
}
} catch (e) {
reject(e);
}
}
//如果Promise狀態為fulfilled回呼這個函式
if (this.PromiseState === 'fulfilled') {
callback(onResolved);
}
//如果Promise狀態為rejected回呼這個函式
if (this.PromiseState === 'rejected') {
callback(onRejected);
}
//如果Promise狀態為pending,保存回呼函式
if (this.PromiseState === 'pending') {
this.callbacks.push({
onResolved: function () {
callback(onResolved);
},
onRejected: function () {
callback(onRejected);
}
})
}
})
}
//添加catch 方法
Promise.prototype.catch = function(onRejected){
return this.then(undefined,onRejected);
}
//添加resolve方法
Promise.resolve = function(value){
//回傳promise物件
return new Promise((resolve,reject) =>{
if(value instanceof Promise){
value.then(v=>{
resolve(v);
},r=>{
reject(r);
})
}else{
resolve(value);
}
})
}
//添加reject方法
Promise.reject = function(reason){
return new Promise((resolve,reject)=>{
reject(reason);
});
}
15. 封裝Promise.all方法:
回傳一個新的promise,只有所有的promise都成功才成功,只要有一個失敗了就直接失敗,失敗了回傳那個失敗值,
// 自定義函式Promise
function Promise(executor){
//添加狀態屬性與結果值屬性
this.PromiseState = 'pending';
this.PromiseResult = null;
// 定義callback屬性,保存pending狀態的回呼函式
this.callbacks = [];
//保存實體物件的this值
const that = this;
//自定義resolve函式,名字不一定用resolve
function resolve(data){
//判斷狀態是否修改過
if(that.PromiseState !== 'pending') return;
//改變狀態屬性
that.PromiseState = 'fulfilled'; // 或者 resolve
//改變結果值屬性
that.PromiseResult =data;
//異步任務成功后執行回呼函式
that.callbacks.forEach(item=>{
item.onResolved(data);
})
}
//自定義reject函式
function reject(data){
//判斷狀態是否修改過,改過就直接回傳
if(that.PromiseState !== 'pending') return;
//改變狀態屬性
that.PromiseState = 'rejected';
//改變結果值屬性
that.PromiseResult =data;
//異步任務失敗后執行回呼函式
that.callbacks.forEach(item=>{
item.onRejected(data);
})
}
try{
//同步呼叫【執行器函式】
executor(resolve,reject);
}catch(e){
//更改Promise物件為失敗
reject(e);
}
}
// 添加then方法
Promise.prototype.then = function (onResolved, onRejected) {
const that = this;
//判斷回呼引數是否存在
if(typeof onRejected !== 'function'){
onRejected = reason =>{
throw reason;
}
}
if(typeof onResolved !== 'function'){
onResolved = value => value;
}
return new Promise((resolve, reject) => {
//封裝重復的部分
function callback(type){
try {
//將結果值傳入
let result = type(that.PromiseResult);
//判斷
if (result instanceof Promise) {
//如果是Promise物件
result.then(v => {
resolve(v);
}, r => {
reject(r);
})
} else {
//結果物件狀態為【成功】
resolve(result);
}
} catch (e) {
reject(e);
}
}
//如果Promise狀態為fulfilled回呼這個函式
if (this.PromiseState === 'fulfilled') {
callback(onResolved);
}
//如果Promise狀態為rejected回呼這個函式
if (this.PromiseState === 'rejected') {
callback(onRejected);
}
//如果Promise狀態為pending,保存回呼函式
if (this.PromiseState === 'pending') {
this.callbacks.push({
onResolved: function () {
callback(onResolved);
},
onRejected: function () {
callback(onRejected);
}
})
}
})
}
//添加catch 方法
Promise.prototype.catch = function(onRejected){
return this.then(undefined,onRejected);
}
//添加resolve方法
Promise.resolve = function(value){
//回傳promise物件
return new Promise((resolve,reject) =>{
if(value instanceof Promise){
value.then(v=>{
resolve(v);
},r=>{
reject(r);
})
}else{
resolve(value);
}
})
}
//添加reject方法
Promise.reject = function(reason){
return new Promise((resolve,reject)=>{
reject(reason);
});
}
//添加all方法
Promise.all = function(promises){
return new Promise((resolve,reject) => {
//添加變數
let count = 0;
// 存放成功結果陣列
let arr =[];
//遍歷全部
for (let i = 0; i < promises.length; i++) {
promises[i].then(v => {
//能進到證明其為成功
count++;
//保存成功結果
arr[i]=v;
//如果全部成功
if (count === promises.length) {
//狀態為成功
resolve(arr);
}
}, r => {
//能進到證明其為失敗
reject(r);
});
}
});
}
試一下:
let p1 = new Promise((resolve,reject)=>{
resolve('_(′?`」 ∠)_');
});
let p2 = Promise.resolve('ok');
let p3 = Promise.resolve('yes');
let res = Promise.all([p1,p2,p3]);
console.log(res);
結果:

16. 封裝Promise.race方法:
回傳一個新的promise,第一個完成的promise的結果狀態改變的就是最終的結果狀態,
上面重復的代碼就不寫上了:
//添加race方法
Promise.race = function(promises){
return new Promise((resolve,reject) => {
//遍歷全部
for (let i = 0; i < promises.length; i++) {
promises[i].then(v => {
//能進到證明其為成功
//狀態為成功
resolve(v);
}, r => {
//能進到證明其為失敗
reject(r);
})
}
});
}
試一下:
let p1 = new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve('_(′?`」 ∠)_');
})
});
let p2 = Promise.resolve('ok');
let p3 = Promise.resolve('yes');
let res = Promise.race([p1,p2,p3]);
console.log(res);
沒毛病:

17.回呼函式異步執行:
上面回呼函式還是同步執行的,要讓 then()回呼函式異步執行,
添加定時器模仿異步操作:
// 自定義函式Promise
function Promise(executor){
//添加狀態屬性與結果值屬性
this.PromiseState = 'pending';
this.PromiseResult = null;
// 定義callback屬性,保存pending狀態的回呼函式
this.callbacks = [];
//保存實體物件的this值
const that = this;
//自定義resolve函式,名字不一定用resolve
function resolve(data) {
//判斷狀態是否修改過
if (that.PromiseState !== 'pending') return;
//改變狀態屬性
that.PromiseState = 'fulfilled'; // 或者 resolve
//改變結果值屬性
that.PromiseResult = data;
//異步任務成功后執行回呼函式
setTimeout(() => {
that.callbacks.forEach(item => {
item.onResolved(data);
})
});
}
//自定義reject函式
function reject(data) {
//判斷狀態是否修改過,改過就直接回傳
if (that.PromiseState !== 'pending') return;
//改變狀態屬性
that.PromiseState = 'rejected';
//改變結果值屬性
that.PromiseResult = data;
//異步任務失敗后執行回呼函式
setTimeout(() => {
that.callbacks.forEach(item => {
item.onRejected(data);
})
});
}
try{
//同步呼叫【執行器函式】
executor(resolve,reject);
}catch(e){
//更改Promise物件為失敗
reject(e);
}
}
// 添加then方法
Promise.prototype.then = function (onResolved, onRejected) {
const that = this;
//判斷回呼引數是否存在
if(typeof onRejected !== 'function'){
onRejected = reason =>{
throw reason;
}
}
if(typeof onResolved !== 'function'){
onResolved = value => value;
}
return new Promise((resolve, reject) => {
//封裝重復的部分
function callback(type){
try {
//將結果值傳入
let result = type(that.PromiseResult);
//判斷
if (result instanceof Promise) {
//如果是Promise物件
result.then(v => {
resolve(v);
}, r => {
reject(r);
})
} else {
//結果物件狀態為【成功】
resolve(result);
}
} catch (e) {
reject(e);
}
}
//如果Promise狀態為fulfilled回呼這個函式
if (this.PromiseState === 'fulfilled') {
setTimeout(()=>{
callback(onResolved);
});
}
//如果Promise狀態為rejected回呼這個函式
if (this.PromiseState === 'rejected') {
setTimeout(()=>{
callback(onRejected);
});
}
//如果Promise狀態為pending,保存回呼函式
if (this.PromiseState === 'pending') {
this.callbacks.push({
onResolved: function () {
callback(onResolved);
},
onRejected: function () {
callback(onRejected);
}
})
}
})
}
//添加catch 方法
Promise.prototype.catch = function(onRejected){
return this.then(undefined,onRejected);
}
//添加resolve方法
Promise.resolve = function(value){
//回傳promise物件
return new Promise((resolve,reject) =>{
if(value instanceof Promise){
value.then(v=>{
resolve(v);
},r=>{
reject(r);
})
}else{
resolve(value);
}
})
}
//添加reject方法
Promise.reject = function(reason){
return new Promise((resolve,reject)=>{
reject(reason);
});
}
//添加all方法
Promise.all = function(promises){
return new Promise((resolve,reject) => {
//添加變數
let count = 0;
// 存放成功結果陣列
let arr =[];
//遍歷全部
for (let i = 0; i < promises.length; i++) {
promises[i].then(v => {
//能進到證明其為成功
count++;
//保存成功結果
arr[i]=v;
//如果全部成功
if (count === promises.length) {
//狀態為成功
resolve(arr);
}
}, r => {
//能進到證明其為失敗
reject(r);
});
}
});
}
//添加race方法
Promise.race = function(promises){
return new Promise((resolve,reject) => {
//遍歷全部
for (let i = 0; i < promises.length; i++) {
promises[i].then(v => {
//能進到證明其為成功
//狀態為成功
resolve(v);
}, r => {
//能進到證明其為失敗
reject(r);
})
}
});
}
18.class版本封裝:
最終封裝:
class Promise{
//構造方法
constructor(executor) {
//添加狀態屬性與結果值屬性
this.PromiseState = 'pending';
this.PromiseResult = null;
// 定義callback屬性,保存pending狀態的回呼函式
this.callbacks = [];
//保存實體物件的this值
const that = this;
//自定義resolve函式,名字不一定用resolve
function resolve(data) {
//判斷狀態是否修改過
if (that.PromiseState !== 'pending') return;
//改變狀態屬性
that.PromiseState = 'fulfilled'; // 或者 resolve
//改變結果值屬性
that.PromiseResult = data;
//異步任務成功后執行回呼函式
setTimeout(() => {
that.callbacks.forEach(item => {
item.onResolved(data);
})
});
}
//自定義reject函式
function reject(data) {
//判斷狀態是否修改過,改過就直接回傳
if (that.PromiseState !== 'pending') return;
//改變狀態屬性
that.PromiseState = 'rejected';
//改變結果值屬性
that.PromiseResult = data;
//異步任務失敗后執行回呼函式
setTimeout(() => {
that.callbacks.forEach(item => {
item.onRejected(data);
})
});
}
try{
//同步呼叫【執行器函式】
executor(resolve,reject);
}catch(e){
//更改Promise物件為失敗
reject(e);
}
}
//then方法封裝
then(onResolved,onRejected){
const that = this;
//判斷回呼引數是否存在
if(typeof onRejected !== 'function'){
onRejected = reason =>{
throw reason;
}
}
if(typeof onResolved !== 'function'){
onResolved = value => value;
}
return new Promise((resolve, reject) => {
//封裝重復的部分
function callback(type){
try {
//將結果值傳入
let result = type(that.PromiseResult);
//判斷
if (result instanceof Promise) {
//如果是Promise物件
result.then(v => {
resolve(v);
}, r => {
reject(r);
})
} else {
//結果物件狀態為【成功】
resolve(result);
}
} catch (e) {
reject(e);
}
}
//如果Promise狀態為fulfilled回呼這個函式
if (this.PromiseState === 'fulfilled') {
setTimeout(()=>{
callback(onResolved);
});
}
//如果Promise狀態為rejected回呼這個函式
if (this.PromiseState === 'rejected') {
setTimeout(()=>{
callback(onRejected);
});
}
//如果Promise狀態為pending,保存回呼函式
if (this.PromiseState === 'pending') {
this.callbacks.push({
onResolved: function () {
callback(onResolved);
},
onRejected: function () {
callback(onRejected);
}
})
}
})
}
//catch 方法
catch(onRejected){
return this.then(undefined,onRejected);
}
//resolve方法
static resolve(value){
//回傳promise物件
return new Promise((resolve,reject) =>{
if(value instanceof Promise){
value.then(v=>{
resolve(v);
},r=>{
reject(r);
})
}else{
resolve(value);
}
})
}
//reject方法
static reject(reason){
return new Promise((resolve,reject)=>{
reject(reason);
});
}
//all方法
static all(promises) {
return new Promise((resolve, reject) => {
//添加變數
let count = 0;
// 存放成功結果陣列
let arr = [];
//遍歷全部
for (let i = 0; i < promises.length; i++) {
promises[i].then(v => {
//能進到證明其為成功
count++;
//保存成功結果
arr[i] = v;
//如果全部成功
if (count === promises.length) {
//狀態為成功
resolve(arr);
}
}, r => {
//能進到證明其為失敗
reject(r);
});
}
});
}
//race方法
static race(promises) {
return new Promise((resolve, reject) => {
//遍歷全部
for (let i = 0; i < promises.length; i++) {
promises[i].then(v => {
//能進到證明其為成功
//狀態為成功
resolve(v);
}, r => {
//能進到證明其為失敗
reject(r);
})
}
});
}
}
十一:async函式:
MDN檔案
1.函式的回傳值為promise物件,
2.promise物件的結果由async函式執行的回傳值決定,
3.其實跟 then()方法回傳結果是一樣一樣的,
1.回傳一個非Promise物件,回傳值是resolve,
async function main(){
return '123';
}
let res = main();
console.log(res);

2.如果回傳是一個Promise物件,由回傳結果決定:
如:
async function main(){
return new Promise((resolve,reject)=>{
reject('NO');
});
}
let res = main();
console.log(res);

3.拋出例外也是失敗:
async function main(){
return new Promise((resolve,reject)=>{
reject('NO');
});
}
let res = main();
console.log(res);

十二.await運算式:
MDN檔案
1.await右側的運算式一般為promise物件,但也可以是其它的值,
2.如果運算式是promise物件,await回傳的是promise成功的值,
3.如果運算式是其它值,直接將此值作為await的回傳值,
注意:
1.await 必須寫在async函式中,但async 函式中可以沒有await ,
2.如果await的promise失敗了,就會拋出例外,需要通過try…catch捕獲處理,
1.右側為promise物件:
async function works(){
let p = new Promise((resolve,reject)=>{
resolve('oh yes')
})
let res = await p;
console.log(res);
}
works();
結果:
oh yes
2.右側為其它值:
async function works(){
let p = new Promise((resolve,reject)=>{
resolve('oh yes')
})
// let res = await p;
let res = await 100;
console.log(res);
}
works();
結果:
100
3.如果promise是失敗狀態:
async function works(){
let p = new Promise((resolve,reject)=>{
// resolve('oh yes')
reject('err');
})
try{
let res = await p;
}catch(e){
console.log(e);
}
}
works();

十三.async與await結合發生ajax請求:
效果: 點擊按鈕獲取一句名言,
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<button id="btn">獲取一句名言</button>
<script>
function sendAJAX(url) {
return new Promise((resolve, reject) => {
//創建物件
const xhr = new XMLHttpRequest();
xhr.responseType = 'json';
//初始化
xhr.open('GET', url);
//發送
xhr.send();
//處理回應結果
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status >= 200 && xhr.status < 300) {
//輸出回應體
resolve(xhr.response);
} else {
//輸出回應狀態碼
reject(xhr.status);
}
}
}
});
}
var btn = document.querySelector("#btn");
btn.addEventListener('click',async function(){
let word = await sendAJAX("http://poetry.apiopen.top/sentences");
console.log(word);
})
</script>
</body>
</html>

十四.總結:
我只想說…

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/276986.html
標籤:其他
上一篇:C/C++學習的準備作業
下一篇:C語言-7(學習C語言的第七天)
