首先回顾下:
1.then需要返回一个promise对象
2.then接收1-2个参数, onFullfilled [,onRejected],后者不一定要写
3.onFullfilled方法中可以返回一下3种类型
1).普通类型(即基本数据类型或者单纯的引用类型)
2).thenable对象,即个人认为具有then方法的对象
3).promise对象
上期内容如上,而上期其实相当于把前两点简单讲了,那么现在来讲讲最终的第三点:
回调函数接收的第一种类型:
基本数据类型或者单纯的引用类型
形如以下格式:
Promise.resolve().then( _ => {
// return 3;
// return {};
// return true;
// return '3';
// ......
})
理解:当返回这些值时,promise会进行判断,只要这些值非thenable对象或者Promise对象,那么统统可以resolve掉
那么第二种:
thenable对象
由于promise实例化虽是同步的,但是then方法却是异步调用,并且属于microTask中,那么此刻的设定就显得及其微妙了,如果单纯内部执行thenable对象then方法,拿到最终状态值,并去修改promise内部状态以及值,那么这个操作却是同步的!为此,实际上我们内部还会再包上一层then方法(此then非thenable上then方法)用以控制异步执行!
而实际上针对thenable的解析却不是很复杂
形如:
Promise.prototype.then(onFullfilled, onRejected) {
// ...两函数判断
let self = this;
return new Promise((res, rej) => {
//3个判断
if(self.status == 'PENDING') {
// 调用onFullfilled方法拿到回调返回的值,再解析
let result = onFullfilled(self.value);
// 传回调进去,成功调res,失败/报错调rej;
resolveIt(result, res, rej);
}
// ...
});
}
function resolveIt(result, res, rej) {
if(result && typeof result == 'Object') {
try {
let then = result.then;
if(typeof then == 'function') {
// 调用thenable对象的then方法,并取出最终的结果值
// 将自定义标准传给thenable对象,同时设定好的thenable对象
// 定义时就说明了调用该方法,由此完成调用
then.call(result, (y) => {resolveIt(y, res, rej)}, () => {});
}else {
resolve(result);
}
} catch(e) {
reject(e);
}
}else {
resolve(result);
}
}
更加需要注意的是,传递了thenable对象,是可以修改内部状态的,从resolved -> reject或者其他等等,只是不能变成pending例如:
Promise.reject(1).then(_ => _, _ => {
return {
then: function(res, rej) {
res(2);
}
}
}).then(_ => console.log(_));
// 2
第三种:
返回promise对象
同以上then方法的code,与thenable的判断类似
以上!有不当之处欢迎讨论
本文探讨Promise的then方法中处理的基本数据类型、thenable对象和Promise对象的情况。当返回非thenable或Promise时,promise会resolve;而对于thenable对象,内部会异步调用其then方法,再包一层then以控制执行;返回Promise对象时,处理方式类似thenable对象。
659

被折叠的 条评论
为什么被折叠?



