Promise

Promise

Promise.js

const PENDING = 'pending'; //初始态
const FULFILLED = 'fulfilled'; // 成功态
const REJECTED = 'rejected'; // 成功态
function Promise(executor) {
    let self = this; //先缓存当前promise实例
    self.status = PENDING; //设置状态
    // 定义存放成功回调的数组
    self.onResolvedCallbacks = [];
    // 定义存放失败回调的数组
    self.onRejectedCallbacks = [];
    // 当调用此方法的时候,如果 promise 状态为 pending 的话可以转换成 成功态,如果已经是成功态或者失败态 则什么也不做
    // 2.1
    function resolve(value) { // 2.1.1
        if (value instanceof Promise) {
            return value.then(resolve, reject)
        }
        setTimeout(function () {
            // 如果是初始态,则转成成功态
            if (self.status == PENDING) {
                self.status = FULFILLED;
                self.value = value; // 成功后会得到一个值,这个值不能改
                // 调用所有成功的回调
                self.onResolvedCallbacks.forEach(cb => cb(self.value));
            }
        });
    }
    function reject(reason) { // 2.1.2
        setTimeout(function () {
            // 如果是初始态,则转成失败态
            if (self.status == PENDING) {
                self.status = REJECTED
                self.value = reason; // 把失败的原因给了 value
                self.onRejectedCallbacks.forEach(cb => cb(self.vaule));
            }
        })
    }
    try {
        // 因为此函数执行可能出异常,所以需要捕获,如果出错了,需要用错误对象 reject
        executor(resolve, reject);
    } catch (e) {
        // 如果这个函数执行失败了,则用失败的原因 reject 这个 promise
        reject(e);
    }
}
function resolvePromise(promise2, x, resolve, reject) {
    if (promise2 === x) {
        return reject(new TypeError('循环引用'));
    }
    let called = false; // promise2 是否已经 resolve 或 reject 了
    if (x instanceof Promise) {
        if (x.status == PENDING) {
            x.then(function (y) {
                resolvePromise(promise2, y, resolve, reject)
            }, reject)
        } else {
            x.then(resolve, reject)
        }
        // x 是一个 thenable 对象或函数,只要有 then 方法的对象,
    } else if (x != null && ((typeof x == 'object') || (typeof x == 'function'))) {
        // 当我们的 promise 和别的 promise 进行交互,编写这段代码的时候尽量的考虑兼容性,允许别人瞎写
        try {
            let then = x.then
            if (typeof then == 'function') {
                // 有些 promise 会同时执行成功和失败的回调
                then.call(x, function (y) {
                    // 如果 promise2 已经成功或失败了,则不会再处理了
                    if (called) return;
                    called = true;
                    resolvePromise(promise2, y, resolve, reject)
                }, function (err) {
                    if (called) return;
                    called = true;
                    reject(err)
                })
            } else {
                // 到此的话 x 不是一个 thenable 对象,那直接把它当成值 resolve promise2 就可以了
                resolve(x)
            }
        } catch (error) {
            if (called) return;
            called = true;
            reject(error)
        }
    } else {
        // 如果 x 是一个普通的值,则用 x 的值去 resolve promise2
        resolve(x)
    }
}
// onFulfilled 是用来接收 promise 成功的值或者失败的原因
Promise.prototype.then = function (onFulfilled, onRejected) {
    // 如果成功和失败的回调没有传,则表示这个 then 没有任何逻辑,只会把值往后抛
    // 2.2.1
    onFulfilled = typeof onFulfilled == 'function' ? onFulfilled : function (value) { return value };
    onRejected = typeof onRejected == 'function' ? onRejected : reason => { throw reason };
    // 如果当前的 promise 状态已经是成功态了,onFulfilled 直接取值
    let self = this;
    let promise2;
    if (self.status == FULFILLED) {
        return promise2 = new Promise(function (resolve, reject) {
            setTimeout(function () {
                try {
                    let x = onFulfilled(self.value);
                    // 如果获取到了返回值 x,会走解析 promise 的过程
                    resolvePromise(promise2, x, resolve, reject);
                } catch (error) {
                    // 如果执行成功的回调过程中出错了,用错误原因把 promise2 reject
                    reject(error);
                }
            })
        })
    }
    if (self.status == REJECTED) {
        return promise2 = new Promise(function (resolve, reject) {
            setTimeout(function () {
                try {
                    let x = onRejected(self.value);
                    resolvePromise(promise2, x, resolve, reject);
                } catch (error) {
                    reject(error);
                }
            })
        })
    }
    if (self.status == PENDING) {
        return promise2 = new Promise(function (resolve, reject) {
            self.onResolvedCallbacks.push(function () {
                // setTimeout(function () {
                    try {
                        let x = onFulfilled(self.value);
                        resolvePromise(promise2, x, resolve, reject);
                    } catch (error) {
                        reject(error);

                    }
                // })
            })
            self.onRejectedCallbacks.push(function () {
                // setTimeout(function () {
                    try {
                        let x = onRejected(self.value);
                        resolvePromise(promise2, x, resolve, reject);
                    } catch (error) {
                        reject(error);
                    }
                // })
            })
        })
    }

}

// catch 原理就是只传失败的回调
Promise.prototype.catch = function (onReject) {
    this.then(null, onRejected)
}
Promise.deferred = Promise.defer = function () {
    let defer = {};
    defer.promise = new Promise(function (resolve, reject) {
        defer.resolve = resolve;
        defer.reject = reject;
    });
    return defer;
}
module.exports = Promise;

测试 Promise

cnpm i -g promises-aplus-tests
promises-aplus-tests Promise.js

Promise.all

Promise.all = function (promises) {
    return new Promise(function (resolve, reject) {
        let result = []
        let count = 0
        function done(i,data) {
            result[i] = data
            if(++count == promises.length) {
                resolve(result)
            }
        }
        for (let i = 0, j = promises.length; i < j; i++) {
            // promises[i].then(done.bind(null,i))
            promises[i].then(function(data){
                done(i,data)
            })
        }
    })
}

测试 Promise.all

index.js

let Promise = require('./Promise')
let p1 = new Promise(function (resolve, reject) {
    setTimeout(function () { 
        reject('err')
    }, 1000)
})
let p2 = new Promise(function (resolve, reject) {
    setTimeout(function () { 
        resolve(200)
    }, 2000)
})

Promise.all([p1,p2]).then(function(data) {
    console.log(data)
},function(err){
    console.log(err)
})

Promise.js

const PENDING = 'pending'; //初始态
const FULFILLED = 'fulfilled'; // 成功态
const REJECTED = 'rejected'; // 成功态
function Promise(executor) {
    let self = this; //先缓存当前promise实例
    self.status = PENDING; //设置状态
    // 定义存放成功回调的数组
    self.onResolvedCallbacks = [];
    // 定义存放失败回调的数组
    self.onRejectedCallbacks = [];
    // 当调用此方法的时候,如果 promise 状态为 pending 的话可以转换成 成功态,如果已经是成功态或者失败态 则什么也不做
    // 2.1
    function resolve(value) { // 2.1.1
        if (value instanceof Promise) {
            return value.then(resolve, reject)
        }
        setTimeout(function () {
            // 如果是初始态,则转成成功态
            if (self.status == PENDING) {
                self.status = FULFILLED;
                self.value = value; // 成功后会得到一个值,这个值不能改
                // 调用所有成功的回调
                self.onResolvedCallbacks.forEach(cb => cb(self.value));
            }
        });
    }
    function reject(reason) { // 2.1.2
        setTimeout(function () {
            // 如果是初始态,则转成失败态
            if (self.status == PENDING) {
                self.status = REJECTED
                self.value = reason; // 把失败的原因给了 value
                self.onRejectedCallbacks.forEach(cb => cb(self.vaule));
            }
        })
    }
    try {
        // 因为此函数执行可能出异常,所以需要捕获,如果出错了,需要用错误对象 reject
        executor(resolve, reject);
    } catch (e) {
        // 如果这个函数执行失败了,则用失败的原因 reject 这个 promise
        reject(e);
    }
}
function resolvePromise(promise2, x, resolve, reject) {
    if (promise2 === x) {
        return reject(new TypeError('循环引用'));
    }
    let called = false; // promise2 是否已经 resolve 或 reject 了
    if (x instanceof Promise) {
        if (x.status == PENDING) {
            x.then(function (y) {
                resolvePromise(promise2, y, resolve, reject)
            }, reject)
        } else {
            x.then(resolve, reject)
        }
        // x 是一个 thenable 对象或函数,只要有 then 方法的对象,
    } else if (x != null && ((typeof x == 'object') || (typeof x == 'function'))) {
        // 当我们的 promise 和别的 promise 进行交互,编写这段代码的时候尽量的考虑兼容性,允许别人瞎写
        try {
            let then = x.then
            if (typeof then == 'function') {
                // 有些 promise 会同时执行成功和失败的回调
                then.call(x, function (y) {
                    // 如果 promise2 已经成功或失败了,则不会再处理了
                    if (called) return;
                    called = true;
                    resolvePromise(promise2, y, resolve, reject)
                }, function (err) {
                    if (called) return;
                    called = true;
                    reject(err)
                })
            } else {
                // 到此的话 x 不是一个 thenable 对象,那直接把它当成值 resolve promise2 就可以了
                resolve(x)
            }
        } catch (error) {
            if (called) return;
            called = true;
            reject(error)
        }
    } else {
        // 如果 x 是一个普通的值,则用 x 的值去 resolve promise2
        resolve(x)
    }
}
// onFulfilled 是用来接收 promise 成功的值或者失败的原因
Promise.prototype.then = function (onFulfilled, onRejected) {
    // 如果成功和失败的回调没有传,则表示这个 then 没有任何逻辑,只会把值往后抛
    // 2.2.1
    onFulfilled = typeof onFulfilled == 'function' ? onFulfilled : function (value) { return value };
    onRejected = typeof onRejected == 'function' ? onRejected : reason => { throw reason };
    // 如果当前的 promise 状态已经是成功态了,onFulfilled 直接取值
    let self = this;
    let promise2;
    if (self.status == FULFILLED) {
        return promise2 = new Promise(function (resolve, reject) {
            setTimeout(function () {
                try {
                    let x = onFulfilled(self.value);
                    // 如果获取到了返回值 x,会走解析 promise 的过程
                    resolvePromise(promise2, x, resolve, reject);
                } catch (error) {
                    // 如果执行成功的回调过程中出错了,用错误原因把 promise2 reject
                    reject(error);
                }
            })
        })
    }
    if (self.status == REJECTED) {
        return promise2 = new Promise(function (resolve, reject) {
            setTimeout(function () {
                try {
                    let x = onRejected(self.value);
                    resolvePromise(promise2, x, resolve, reject);
                } catch (error) {
                    reject(error);
                }
            })
        })
    }
    if (self.status == PENDING) {
        return promise2 = new Promise(function (resolve, reject) {
            self.onResolvedCallbacks.push(function () {
                // setTimeout(function () {
                try {
                    let x = onFulfilled(self.value);
                    resolvePromise(promise2, x, resolve, reject);
                } catch (error) {
                    reject(error);

                }
                // })
            })
            self.onRejectedCallbacks.push(function () {
                // setTimeout(function () {
                try {
                    let x = onRejected(self.value);
                    resolvePromise(promise2, x, resolve, reject);
                } catch (error) {
                    reject(error);
                }
                // })
            })
        })
    }

}

// catch 原理就是只传失败的回调
Promise.prototype.catch = function (onReject) {
    this.then(null, onRejected)
}
Promise.deferred = Promise.defer = function () {
    let defer = {};
    defer.promise = new Promise(function (resolve, reject) {
        defer.resolve = resolve;
        defer.reject = reject;
    });
    return defer;
}
Promise.all = function (promises) {
    return new Promise(function (resolve, reject) {
        let result = []
        let count = 0
        function done(i,data) {
            result[i] = data
            if(++count == promises.length) {
                resolve(result)
            }
        }
        for (let i = 0, j = promises.length; i < j; i++) {
            // promises[i].then(done.bind(null,i))
            promises[i].then(function(data){
                done(i,data)
            })
        }
    })
}
module.exports = Promise;

Promise.all 2

function gen(times,cb) {
    let result = []
    let count = 0
    return function(i, data) {
        result[i] = data
        if (++count == times) {
            cb(result)
        }
    }
}
Promise.all = function (promises) {
    return new Promise(function (resolve, reject) {
        // let result = []
        // let count = 0
        // function done(i, data) {
        //     result[i] = data
        //     if (++count == promises.length) {
        //         resolve(result)
        //     }
        // }
        let done = gen(promises.length,resolve)
        for (let i = 0, j = promises.length; i < j; i++) {
            // promises[i].then(done.bind(null,i))
            promises[i].then(function (data) {
                done(i, data)
            },reject)
        }
    })
}

Promise.race

Promise.race = function (promises) {
    return new Promise(function (resolve, reject) {
        for (let i = 0, j = promises.length; i < j; i++) {
            promises[i].then(resolve, reject)
        }
    })
}

测试 Promise.race

Promise.race([p1,p2]).then(function(data) {
    console.log(data)
},function(err) {
    console.log(err)
})

Promise.js 最终

const PENDING = 'pending'; //初始态
const FULFILLED = 'fulfilled'; // 成功态
const REJECTED = 'rejected'; // 成功态
function Promise(executor) {
    let self = this; //先缓存当前promise实例
    self.status = PENDING; //设置状态
    // 定义存放成功回调的数组
    self.onResolvedCallbacks = [];
    // 定义存放失败回调的数组
    self.onRejectedCallbacks = [];
    // 当调用此方法的时候,如果 promise 状态为 pending 的话可以转换成 成功态,如果已经是成功态或者失败态 则什么也不做
    // 2.1
    function resolve(value) { // 2.1.1
        if (value instanceof Promise) {
            return value.then(resolve, reject)
        }
        setTimeout(function () {
            // 如果是初始态,则转成成功态
            if (self.status == PENDING) {
                self.status = FULFILLED;
                self.value = value; // 成功后会得到一个值,这个值不能改
                // 调用所有成功的回调
                self.onResolvedCallbacks.forEach(cb => cb(self.value));
            }
        });
    }
    function reject(reason) { // 2.1.2
        setTimeout(function () {
            // 如果是初始态,则转成失败态
            if (self.status == PENDING) {
                self.status = REJECTED
                self.value = reason; // 把失败的原因给了 value
                self.onRejectedCallbacks.forEach(cb => cb(self.vaule));
            }
        })
    }
    try {
        // 因为此函数执行可能出异常,所以需要捕获,如果出错了,需要用错误对象 reject
        executor(resolve, reject);
    } catch (e) {
        // 如果这个函数执行失败了,则用失败的原因 reject 这个 promise
        reject(e);
    }
}
function resolvePromise(promise2, x, resolve, reject) {
    if (promise2 === x) {
        return reject(new TypeError('循环引用'));
    }
    let called = false; // promise2 是否已经 resolve 或 reject 了
    if (x instanceof Promise) {
        if (x.status == PENDING) {
            x.then(function (y) {
                resolvePromise(promise2, y, resolve, reject)
            }, reject)
        } else {
            x.then(resolve, reject)
        }
        // x 是一个 thenable 对象或函数,只要有 then 方法的对象,
    } else if (x != null && ((typeof x == 'object') || (typeof x == 'function'))) {
        // 当我们的 promise 和别的 promise 进行交互,编写这段代码的时候尽量的考虑兼容性,允许别人瞎写
        try {
            let then = x.then
            if (typeof then == 'function') {
                // 有些 promise 会同时执行成功和失败的回调
                then.call(x, function (y) {
                    // 如果 promise2 已经成功或失败了,则不会再处理了
                    if (called) return;
                    called = true;
                    resolvePromise(promise2, y, resolve, reject)
                }, function (err) {
                    if (called) return;
                    called = true;
                    reject(err)
                })
            } else {
                // 到此的话 x 不是一个 thenable 对象,那直接把它当成值 resolve promise2 就可以了
                resolve(x)
            }
        } catch (error) {
            if (called) return;
            called = true;
            reject(error)
        }
    } else {
        // 如果 x 是一个普通的值,则用 x 的值去 resolve promise2
        resolve(x)
    }
}
// onFulfilled 是用来接收 promise 成功的值或者失败的原因
Promise.prototype.then = function (onFulfilled, onRejected) {
    // 如果成功和失败的回调没有传,则表示这个 then 没有任何逻辑,只会把值往后抛
    // 2.2.1
    onFulfilled = typeof onFulfilled == 'function' ? onFulfilled : function (value) { return value };
    onRejected = typeof onRejected == 'function' ? onRejected : reason => { throw reason };
    // 如果当前的 promise 状态已经是成功态了,onFulfilled 直接取值
    let self = this;
    let promise2;
    if (self.status == FULFILLED) {
        return promise2 = new Promise(function (resolve, reject) {
            setTimeout(function () {
                try {
                    let x = onFulfilled(self.value);
                    // 如果获取到了返回值 x,会走解析 promise 的过程
                    resolvePromise(promise2, x, resolve, reject);
                } catch (error) {
                    // 如果执行成功的回调过程中出错了,用错误原因把 promise2 reject
                    reject(error);
                }
            })
        })
    }
    if (self.status == REJECTED) {
        return promise2 = new Promise(function (resolve, reject) {
            setTimeout(function () {
                try {
                    let x = onRejected(self.value);
                    resolvePromise(promise2, x, resolve, reject);
                } catch (error) {
                    reject(error);
                }
            })
        })
    }
    if (self.status == PENDING) {
        return promise2 = new Promise(function (resolve, reject) {
            self.onResolvedCallbacks.push(function () {
                // setTimeout(function () {
                try {
                    let x = onFulfilled(self.value);
                    resolvePromise(promise2, x, resolve, reject);
                } catch (error) {
                    reject(error);

                }
                // })
            })
            self.onRejectedCallbacks.push(function () {
                // setTimeout(function () {
                try {
                    let x = onRejected(self.value);
                    resolvePromise(promise2, x, resolve, reject);
                } catch (error) {
                    reject(error);
                }
                // })
            })
        })
    }

}

// catch 原理就是只传失败的回调
Promise.prototype.catch = function (onReject) {
    this.then(null, onRejected)
}
Promise.deferred = Promise.defer = function () {
    let defer = {};
    defer.promise = new Promise(function (resolve, reject) {
        defer.resolve = resolve;
        defer.reject = reject;
    });
    return defer;
}
function gen(times, cb) {
    let result = []
    let count = 0
    return function (i, data) {
        result[i] = data
        if (++count == times) {
            cb(result)
        }
    }
}
Promise.all = function (promises) {
    return new Promise(function (resolve, reject) {
        // let result = []
        // let count = 0
        // function done(i, data) {
        //     result[i] = data
        //     if (++count == promises.length) {
        //         resolve(result)
        //     }
        // }
        let done = gen(promises.length, resolve)
        for (let i = 0, j = promises.length; i < j; i++) {
            promises[i].then(function (data) {
                done(i, data)
            }, reject)
        }
    })
}
Promise.race = function (promises) {
    return new Promise(function (resolve, reject) {
        for (let i = 0, j = promises.length; i < j; i++) {
            promises[i].then(resolve, reject)
        }
    })
}
// 返回一个立刻成功的 Promise
// 别人提供 给你一个方法,需要你传入一个 Promise,但你只有一个普通的值,你就可以通过这个方法把这个普通的值(string number object)转成一个 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)
    })
}
module.exports = Promise;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值