Promise 實(shí)現(xiàn)

  1. 創(chuàng)建一個 Promise.js 文件
function Promise(executor) { // executor是一個執(zhí)行函數(shù)
    let self = this;
    self.status = 'pending';
    self.value = undefined; // 默認(rèn)成功的值
    self.reason = undefined; // 默認(rèn)失敗的原因
    self.onResolvedCallbacks = []; // 存放then成功的回調(diào)
    self.onRejectedCallbacks = []; // 存放then失敗的回調(diào)
    function resolve(value) { // 成功狀態(tài)
        if (self.status === 'pending') {
            self.status = 'resolved';
            self.value = value;
            self.onResolvedCallbacks.forEach(function (fn) {
                fn();
            });
        }
    }
    function reject(reason) { // 失敗狀態(tài)
        if (self.status === 'pending') {
            self.status = 'rejected';
            self.reason = reason;
            self.onRejectedCallbacks.forEach(function (fn) {
                fn();
            })
        }
    }
    try {
        executor(resolve, reject)
    } catch (e) { // 捕獲的時候發(fā)生異常,就直接失敗了
        reject(e);
    }
}
function resolvePromise(promise2, x, resolve, reject) {
    // 有可能這里返回的x是別人的promise
    // 盡可能允許其他亂寫
    if (promise2 === x) { //這里應(yīng)該報一個類型錯誤,有問題
        return reject(new TypeError('循環(huán)引用了'))
    }
    // 看x是不是一個promise,promise應(yīng)該是一個對象
    let called; // 表示是否調(diào)用過成功或者失敗
    if (x !== null && (typeof x === 'object' || typeof x === 'function')) {
        // 可能是promise {},看這個對象中是否有then方法,如果有then我就認(rèn)為他是promise了
        try { // {then:1}
            let then = x.then;
            if (typeof then === 'function') {
                // 成功
                then.call(x, function (y) {
                    if (called) return
                    called = true
                    // y可能還是一個promise,在去解析直到返回的是一個普通值
                    resolvePromise(promise2, y, resolve, reject)
                }, function (err) { //失敗
                    if (called) return
                    called = true
                    reject(err);
                })
            } else {
                resolve(x)
            }
        } catch (e) {
            if (called) return
            called = true;
            reject(e);
        }
    } else { // 說明是一個普通值1
        resolve(x); // 表示成功了
    }
}
Promise.prototype.then = function (onFulfilled, onRjected) {
    //成功和失敗默認(rèn)不穿給一個函數(shù)
    onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : function (value) {
        return value;
    }
    onRjected = typeof onRjected === 'function' ? onRjected : function (err) {
        throw err;
    }
    let self = this;
    let promise2; //返回的promise
    if (self.status === 'resolved') {
        promise2 = new Promise(function (resolve, reject) {
            // 當(dāng)成功或者失敗執(zhí)行時有異常那么返回的promise應(yīng)該處于失敗狀態(tài)
            // x可能是一個promise 也有可能是一個普通的值
            setTimeout(function () {
                try {
                    let x = onFulfilled(self.value);
                    // x可能是別人promise,寫一個方法統(tǒng)一處理
                    resolvePromise(promise2, x, resolve, reject);
                } catch (e) {
                    reject(e);
                }
            })
        })
    }
    if (self.status === 'rejected') {
        promise2 = new Promise(function (resolve, reject) {
            setTimeout(function () {
                try {
                    let x = onRjected(self.reason);
                    resolvePromise(promise2, x, resolve, reject);
                } catch (e) {
                    reject(e);
                }
            })

        })
    }
    // 當(dāng)調(diào)用then時可能沒成功 也沒失敗
    if (self.status === 'pending') {
        promise2 = new Promise(function (resolve, reject) {
            // 此時沒有resolve 也沒有reject
            self.onResolvedCallbacks.push(function () {
                setTimeout(function () {
                    try {
                        let x = onFulfilled(self.value);
                        resolvePromise(promise2, x, resolve, reject);
                    } catch (e) {
                        reject(e)
                    }
                })
            });
            self.onRejectedCallbacks.push(function () {
                setTimeout(function () {
                    try {
                        let x = onRjected(self.reason);
                        resolvePromise(promise2, x, resolve, reject);
                    } catch (e) {
                        reject(e);
                    }
                })
            });
        })
    }
    return promise2;
}
// 捕獲錯誤的方法
Promise.prototype.catch = function (callback) {
    return this.then(null, callback)
}
// 解析全部方法
// let arr = [];
// arr[1] = 100;
// console.log(arr.length)
Promise.all = function (promises) {
    //promises是一個promise的數(shù)組
    return new Promise(function (resolve, reject) {
        let arr = []; //arr是最終返回值的結(jié)果
        let i = 0; // 表示成功了多少次
        function processData(index, y) {
            arr[index] = y;
            if (++i === promises.length) {
                resolve(arr);
            }
        }
        for (let i = 0; i < promises.length; i++) {
            promises[i].then(function (y) {
                processData(i, y)
            }, reject)
        }
    })
}
// 只要有一個promise成功了 就算成功。如果第一個失敗了就失敗了
Promise.race = function (promises) {
    return new Promise(function (resolve, reject) {
        for (var i = 0; i < promises.length; i++) {
            promises[i].then(resolve,reject)
        }
    })
}
// 生成一個成功的promise
Promise.resolve = function(value){
    return new Promise(function(resolve,reject){
        resolve(value);
    })
}
// 生成一個失敗的promise
Promise.reject = function(reason){
    return new Promise(function(resolve,reject){
        reject(reason);
    })
}
Promise.defer = Promise.deferred = function () {
    let dfd = {};
    dfd.promise = new Promise(function (resolve, reject) {
        dfd.resolve = resolve;
        dfd.reject = reject;
    });
    return dfd
}
module.exports = Promise;
  1. 其他文件中引入
let Promise = require('./Promise')
// 同步調(diào)用的
let p = new Promise(function(resolve, reject){
    // 如果兩個都調(diào)用,誰在前,就調(diào)誰。
    reject(100);
    resolve(1);
})
// then 接受兩個回調(diào)函數(shù),一個是成功的回調(diào),一個是失敗的回調(diào)
p.then(function(data){
    console.log('data', data)
},function(err){
    console.log('err', err)
})

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容