-
Notifications
You must be signed in to change notification settings - Fork 20
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
promise #12
Labels
Comments
最简单实现 // 如果有obj有then属性函数,则返回一个then函数,this绑定到obj,接受使用then时的参数
function getThen(obj) {
var then = obj && obj.then;
if (obj && typeof obj === 'object' && typeof then === 'function') {
return function appyThen() {
// this绑定到boj并执行then方法
then.apply(obj, arguments);
};
}
}
// 如果resolve(res)的res还是一个promise,则先执行完自己的resolve,再继续执行res的then方法,this绑定到res
// 这里可以将res的所有then方法递归完
function executeCallback(type, x) {
var isResolve = type === 'resolve',
thenable;
// 如果客户使用resolve(res)时,res是一个函数或者对象,x就是res,则去判断
// res是否有then属性函数,有则返回一个绑定res作为this的函数
if (isResolve && (typeof x === 'object' || typeof x === 'function')) {
try {
// 如果x有then方法,则返回一个then函数,this绑定到x,参数是使用thenable函数时thenable函数的参数
// thenable是一个函数
thenable = getThen(x);
} catch (e) {
return executeCallback.bind(this)('reject', e);
}
}
if (isResolve && thenable) {
// 递归执行resolve(res)的res.then方法,并绑定this到第一个res上
// 一开始this指向最外层的promise,所以执行完resolve后就能执行then了
// 这里执行this所在的then
executeResolver.bind(this)(thenable);
} else {
this.state = isResolve ? RESOLVED : REJECTED;
this.data = x;
this.callbackQueue.forEach(v => v[type](x));
}
return this;
}
// 用于执行 new Promise(function(resolve, reject){}) 中的resove或reject方法
function executeResolver(resolver) {
//[标准 2.3.3.3.3] 如果resove()方法多次调用,只响应第一次,后面的忽略
var called = false,
// 把this存起来,让执行onSuccess还能访问到这个promise对象的属性
_this = this;
// 执行reject,没有返回
function onError(y) {
if (called) {
return; }
called = true;
//[标准 2.3.3.3.2] 如果是错误 使用reject方法
executeCallback.bind(_this)('reject', y);
}
// 执行resolve函数, 这里的执行不知道是什么时候的执行,因为是异步的
// 这个函数是由用户去触发执行的,就是那个resolve(res);
function onSuccess(r) {
if (called) {
return; }
called = true;
// 一开始this指向最外层的promise,所以执行完resolve后就能执行then了
executeCallback.bind(_this)('resolve', r);
}
try {
// 执行成功的函数是由封装的函数作为一个参数提供给用户使用的
//[标准 2.3.3.3.4] 如果调用resolve()或reject()时发生错误,则将状态改成rejected,并将错误reject出去
resolver(onSuccess, onError);
} catch (e) {
onError(e);
}
}
function Promise(resolver) {
if (resolver && typeof resolver !== 'function') {
throw new Error('Promise resolver is not a function') }
// PENDING Fulfilled Rejected
this.state = PENDING;
//当前promise对象的数据(成功或失败)
this.data = UNDEFINED;
//当前promise对象注册的回调队列
this.callbackQueue = [];
if (resolver) executeResolver.call(this, resolver);
}
Promise.prototype.then = function(onResolved, onRejected) {
if (typeof onResolved !== 'function' && this.state === RESOLVED ||
typeof onRejected !== 'function' && this.state === REJECTED) {
return this;
}
var promise = new this.constructor();
if (this.state !== PENDING) {
var callback = this.state === RESOLVED ? onResolved : onRejected;
executeCallbackAsync.bind(promise)(callback, this.data);
} else {
this.callbackQueue.push(new CallbackItem(promise, onResolved, onRejected))
}
// 链式调用
return promise;
}
Promise.prototype['catch'] = function(onRejected) {
return this.then(null, onRejected);
}
# 总结
1. resolve函数执行的时候通过`var promise = new this.constructor();`生成一个promise返回
2. resolve之后是如何切换到then的,这是一个问题 |
Open
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
技术说明
prototype
new原理
实现一个new
实现
引用:
深入理解 Promise (上)
深入理解 Promise (中)
深入理解 Promise (下)
The text was updated successfully, but these errors were encountered: