JavaScript之異步處理 Promise理解

promise 就是ES6新語法中 新增解決異步處理的一種方法 解決異步處理 並返回成功與失敗的數據
其他方法 async await、回調函數、generator yleid
promise 中的狀態
                起始狀態爲 pending
                成功狀態爲 resolved
                失敗狀態爲 rejected
注意: promise 只能從起始狀態改爲成功或失敗的某一種狀態 且爲單向改變(不可逆)
無論成功還是失敗,都會有一個結果數據
              成功爲對應的成功數據返回值
              失敗爲對應的失敗數據返回值
                                                        resolve resolved then onResolved()/onRejected()
new Promise 返回新的promise       

                                                          reject rejected finall/catch onRejected()
promise的優勢
1. promise指定回調函數更加靈活
      普通回調: 必須在異步函數執行前 指定回調函數
      promise: 異步函數執行前/中/後 都可以指定
      promise 的狀態通過回調函數的方式確定 當存在鏈式調用時 then方法由上一級的返回結果決定
new Promise((resolve,reject)=>{
             resolve(1);
})
.then(
          (res)=>{
                     return Promise.reject(2)
           },
          (err)=>{}).then(
          (res)=>{},
          (err)=>{
                   console.log(2);
           }
)
promise 對reject 返回的數據 .then中沒有對應的回調函數接收 就默認爲 err => throw err 一直向下拋 直至遇到處理的函數
promise 對於 .then中有 能處理的 reject 的回調函數 那麼就執行該回調 若後面還有.then 方法 則執行成功方法
promise 中 .then 或 .catch 接收的狀態爲 reject 或者 resolve 當爲pending狀態時 .then .catch ... 都不會被調用
使用 return new Promise(()=>{}) 狀態爲 pending 中斷後續執行

 

const PENDING = "pending";
const RESOLVED = "resolved";
const REJECTED = "rejected";
// 定義Promise構造函數
class Promise{
    //actuator 是一個執行器 包含了 resolve reject
    constructor(actuator){
        //起始狀態爲pending
        this.status = PENDING;
        //保存傳輸的數據
        this.data = undefined;
        //保存回調函數 保存數據爲 [{onResolved1,onRejected1},{onResolved2,onRejected2}]
        this.callback = [];
        //防止this發生改變 使用self 保存
        const self = this;
        // 定義成功方法 
        function resolve(params) {
            // 判斷當前的狀態是否爲pending
            if(self.status!==PENDING){
                return;
            }
            // 保存狀態以及傳遞數據
            self.status = RESOLVED;
            self.data = params;
            // 判斷回調函數數組中是否存在待執行的數據
            if(self.callback.length > 0){
                // 由於所有的回調函數都是異步執行的 因此使用setTimeout 進行異步執行
                setTimeout(()=>{
                    // 遍歷數組 執行對應的成功回調函數
                    self.callback.forEach(item =>{
                        item.onResolved();
                    })
                },0)
            }
        }
        // 失敗方法 與 成功方法類似
        function reject(params) {
            if(self.status!==PENDING){
                return;
            }
            self.status = REJECTED;
            self.data = params;
            if(self.callback.length > 0){
                setTimeout(()=>{
                    self.callback.forEach(item =>{
                        item.onRejected();
                    })
                },0)
            }
        }
        // 判斷執行器是否存在異常 如果存在異常 則執行錯誤方法
        try{
            actuator(resolve,reject)
        }catch (e) {
            reject(e)
        }
    }
    // then方法爲核心方法  傳遞兩個回調函數 成功、失敗
    then(onResolved,onRejected){
        // 判斷這兩個函數 都否爲函數 如果不是則 使其爲一個函數
        onResolved = typeof onResolved === "function" ? onResolved : value => value;
        onRejected = typeof onRejected === "function" ? onRejected : reason => {throw reason};
        // 保存this
        const self = this;
        // 返回一個新的promise
        return new Promise((resolve,reject)=>{
            // handle函數 主要是判斷then方法傳遞的回調函數執行的返回值的狀態
            // 判斷是promise 還是 普通值 還是錯誤 且讓新的promise的狀態爲返回值的狀態
            function handle(cb) {
                try{
                    // 執行回調獲取返回值
                    const result = cb(self.data);
                    // 修改新的promise狀態
                    if(result instanceof Promise){
                        result.then(resolve,reject);
                    }else{
                        resolve(result);
                    }
                }catch (e) {
                    reject(e);
                }
            }
            // 判斷當前的promise的狀態 使用handle函數 處理對應的then方法的回調函數
            if(self.status === PENDING){ // 等待狀態
                self.callback.push({
                    // 由於在promise中的resolve、reject函數中會執行onResolve與onRejected 但是 新的promise沒有辦法通過promise中的執行結果而改變狀態 因此 在then中改變對應的狀態
                    onResolved(){
                        handle(onResolved);
                    },
                    onRejected(){
                        handle(onRejected);
                    }
                });
            }else if(self.status === RESOLVED){ // 成功狀態
                setTimeout(()=>{
                    handle(onResolved);
                },0)
            }else{ // 失敗狀態
                setTimeout(()=>{
                    handle(onRejected);
                },0)
            }
        })
    }
}

 

new Promise((resolve,reject)=>{
            resolve(0);
        }).then(value => {
            console.log(value);
            return new Promise((resolve,reject)=>{
                // resolve(1);
                reject(5);
            })
        },err=>console.log(err)).then(value=>console.log(value),err=>console.log(err));
/* 結果爲
  0 
  5
*/
發佈了15 篇原創文章 · 獲贊 0 · 訪問量 4181
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章