1.在 new Promise的時候接受一個方法,方法中有resolve和reject兩個方法,分別對應promise狀態改變時的操作
2.promise對象內部存在三種狀態,分別是 pending, fulfilled, rejected,promise
3.對象在創建的時候,會立即執行其中傳入的方法,并且通過resolve和reject方法改變status
4.當 promise.then執行的時候,會傳入onFulfilled和onRejected方法,這時候會檢查promise內部狀態,這里存在三種情況:
一個是pending的時候,說明狀態沒有改變有可能是resolve方法被異步加載,那么會被把傳入的onFulfilled和onRejected方法push到resolveCallbacks和rejectCallbacks隊列當中;
第二種是fulfilled狀態,說明被resolve了,那么就會執行當前的onFulfilled方法
第三種就是rejected狀態,說明被reject了,那么就會執行當前的onRejected方法
5.如果resolve或者reject被異步了,那么就會先通過then將傳入的方法放到callbacks隊列中,等到promise內部resolve或者reject方法執行時,清空callbacks上的方法
6.promise返回的是一個promise對象,promise對象.then返回的仍然是一個promise對象
```js
/**
* promise 狀態:
* pendding: 初始狀態 pendding 可以轉為 fulfilled和 rejected
* fulfilled
* rejected
*/
class Commitment {
static PENDING = "待定";
static FULFILLED = "成功";
static REJECTED = "拒絕";
constructor(func) {
this.status = Commitment.PENDING; // 一開始為 pendding
this.result = null; // 結果
this.resolveCallbacks = [];
this.rejectCallbacks = [];
// 這里需要bind this,否則new實例過程中立即調用func函數,此時還沒有this
// func(this.resolve.bind(this), this.reject.bind(this)) // 傳入后立即執行
try {
func(this.resolve.bind(this), this.reject.bind(this));
} catch (error) {
// 如果報錯,直接執行 reject
this.reject(error);
}
}
// resole和reject是在創建 promise 的過程中調用的
resolve(result) {
// result 為 new Promise 時 resolve(result)中的result
setTimeout(() => {
// resolve 時,如果狀態為 pendding,則改為 fulfilled
if (this.status === Commitment.PENDING) {
this.status = Commitment.FULFILLED;
this.result = result;
// 如果是異步,resolve可能會比 then 后執行
// 檢查 callbacks數組并執行
this.resolveCallbacks.forEach((callback) => {
callback(result);
});
}
});
}
reject(result) {
// reject 的時候,如果狀態為 pendding,則改為 rejected
setTimeout(() => {
if (this.status === Commitment.PENDING) {
this.status = Commitment.REJECTED;
this.result = result;
this.rejectCallbacks.forEach((callback) => {
callback(result);
});
}
});
}
// then 有兩個參數,
// onfulfilled:狀態成功時,執行的回調
// onrejected: 狀態為拒絕時,執行的回調
then(onFULFILLED, onREJECTED) {
return new Commitment((resolve, reject) => {
// 判斷傳入的是否是函數
if (typeof onFULFILLED !== "function") {
onFULFILLED = () => {};
}
if (typeof onREJECTED !== "function") {
onREJECTED = () => {};
}
// 如果是 pendding,說明resolve被異步了,
// 把 then 應該執行的方法放到 resolveCallbacks中
if (this.status === Commitment.PENDING) {
this.resolveCallbacks.push(onFULFILLED);
this.rejectCallbacks.push(onREJECTED);
}
// 如果promise實例執行的是 resolve,則
if (this.status === Commitment.FULFILLED) {
setTimeout(() => {
onFULFILLED(this.result);
});
}
// 如果promise實例執行的是 reject,則
if (this.status === Commitment.REJECTED) {
setTimeout(() => {
onREJECTED(this.result);
});
}
});
}
}
let commitment = new Commitment((resolve, reject) => {
// resolve實際做了兩件事
// 1.把 promise實例內部的 pedding狀態改為 fulfilled
// 2.把 resolve(參數)的參數傳入了promise實例,作為result
resolve("resolve的結果"); // 這里會立即執行 resolve方法
// reject()
// throw new Error('報錯')
});
// commitment.then(
// undefined,
// res => {
// console.log('reject的時候會觸發', res);
// }
// )
console.log("1");
let commitment2 = new Commitment((resolve, reject) => {
// func 會立即執行
console.log("2");
setTimeout(() => {
resolve("3"); // 把 resolve 的內容存在 result 中了
reject("4");
console.log(5);
});
});
commitment2.then(
(result) => {
console.log(result, "6");
},
(result) => {
console.log(result, "7");
}
);
console.log("8");
```
- JavaScript
- 1.數組
- 1.數組Api
- 2.判斷是否為數組
- 3.手寫forEach, map, filter, every, some, reduce
- 4.類數組轉化為數組
- 5.reduce實現compose函數
- 7.sort實現與排序
- 2.類型
- 1. let, const, var
- 1. Number 數字
- 3. Boolean 布爾值
- 4. undefined和null
- 2. String 字符串
- 1. 字符串方法
- 2. 操作字符串實例
- 3. startWith&字符串模板
- 5. 類型轉換
- 4.深拷貝與淺拷貝
- 7.Symbol類型
- typeof 和 instanceof
- Set
- Map
- 3.this,原型,原型鏈
- 1.this
- 2.手寫call, apply, bind
- 3.模擬new操作符
- 4.手寫Object.create
- 4.對象
- proxy代理
- defineProperty數據劫持
- 4.模塊化
- 5.http
- ECMAScript
- 0. 調試&兼容性&錯誤處理
- 3. 運算
- 4. 對象(三種引用類型&正則)
- 1. 數組
- 1. 數組的六種遍歷方法
- 2. 數組的增刪查改
- 3. 操作數組(展開、join、排序...)
- 4. 補充五種ES6方法
- 2. 函數
- 3. JSON
- 4. 正則
- 附:正則表達式特殊字符
- 5. 面向對象
- es6的繼承
- 6. 控制語句
- 7. ajax
- 8. promise
- 9. 閉包
- 1. 閉包產生三個相同隨機數
- 2. 閉包實現點贊
- 10.箭頭函數
- _isEmpty
- Object.assign(target, obj, obj)
- Math.ceil, round,
- DOM
- 3.1 節點
- 3.2 DOM操作元素
- 3.3 fragment DOM碎片
- 5. 事件
- BOM
- 1. window
- 2. navigation檢測訪問類型
- 3. screen窗口大小內容大小
- 4. history
- promise
- 1.promise使用
- 2.手寫promise
- 3.手寫promise.all
- 生成器generator
- 1.generator的使用
- 2.簡單實現generator
- 手寫async await
- async/await
- 5.防抖節流
- 難點深入
- 1. 瀏覽器&js特點
- 2. JS堆棧與深淺拷貝
- 3. 詳解a++和++a的區別
- 4. JS&jQuery獲取元素的方法
- 5. NodeList和HTMLCollection區別
- 6. var與let的區別
- 7. this 與 bind call apply
- 8. get與post請求的區別
- 9. 閉包
- Dom demo
- 1. JQuery--頁面點擊切換效果
- 2. JQuery-load實現頭尾封裝
- 3. JS--添加移除屬性名
- 4. jQuery--eq()與index()
- 5. table隔行變色
- 6. 改變函數this的指向
- 7. jQuery each遍歷
- ECMAScript demo
- 1. 斐波那契數列
- 2. 數組去重
- 3. 自調用函數生成隨機數
- 瀏覽器、DOM
- 1.從輸入url到頁面加載的全過程
- 2.http與https
- 3.v8垃圾回收機制
- 4.dom事件
- 5.跨域
- 6.強緩存和協商緩存
- 3.eventloop,宏任務和微任務
- 1.什么是任務
- 2.執行順序例題
- 3.執行順序例題,添加script
- 4.執行順序,多個宏任務
- 4.HTTP
- 1.經典五層模型
- 2.http發展歷史
- 3.http三次握手
- 4.URI,URL,URN
- 1.http協議
- 2.https
- http狀態碼
- 5.script標簽defer和async區別
- cookie
- connect: keep-alive