一般情况下,用户代码主要用两种方法得到一个promise对象:
-
使用 new Promise来创建一个promise;
-
使用类方法 Promise.xxx()--包括resolve(),reject,all或者race等来获得一个promise;
任何方法得到的promise对象都具有then、catch等方法,也称为 promise.prototype.xxx()原型方法。
javascript约定调用这些方法讲‘绝对’不会跑出异常,而这也是得到一个新的promise对象的第三种方法:
- 使用原型方法promise.prototype.xxx() --- promise.then、catch和finally等将返回一个新的promise。并且,任何一种方法都是立即得到promise对象的。
promise构造方法
const executor = function (resolve, reject) {}
new Promise(executor);
executor是用户定义的执行函数。当js引擎通过new运算创建promise对象时,它事实上会在调用executor()之前就创建好一个新的promise对象的实例,并且得到关联给该实例的两个置值器:resolve和reject,接下来,他会调用executor,并且将resolve与reject作为入口参数传入,而executor函数会被执行直到退出。整个过程看起来像是让用户代码回调js引擎,
new Promise((resolve, reject) => {
resolve(100);
});
注意:当试图用自身来置值,js会抛出个异常
var delayResolve;
p = new Promise((resolve, reject) => {
delayResolve = resolve;
});
delayResolve(p); // TypeError: Chaining cycle detected for promise ...
但是js并不检测交叉的循环引用的resolve置值器
// 尝试 resolve 自身
var delayResolve;
p = new Promise((resolve, reject) => {
delayResolve = resolve;
});
// 将resolve暂存以完成上述实例
var delayResolve2;
p2 = new Promise((resolve, reject) => {
delayResolve2 = resolve;
});
// 循环引用
delayResolve(p2);
delayResolve2(p);
Then链中promise的置值逻辑
一个 prosmie可能会被置入两种值之一,这两种值是指:
- 如果promise被成功resolve,则该值为有效值(value)。
- 如果promise被主动reject或resolve失败,则该值用于记录原因(reason)。
且无论value还是reason都可以是js的任意数据类型。
p = new Promise((resolve, reject) => {
try{
resolve(x)
}catch(e) {
reject(e);
}
});
// 下面是第二种抛出异常的方式
p = new Promise((resolve, reject) => {
if (!ok) throw new Error();
resolve(x);
});
在Then链中,产生 reject 值的方式有两种,一种是通过抛出异常来使js引擎捕获异常对象,另一种是通过Promise.reject来显式地返回。前者是将错误对象作为值,后者得到一个不确定类型的值,它可以是任意的js数据。
Then链对值的传递以及catch处理
这里还存在一种最为特殊的情况:如果promise的resolve并没有关联有效的onFulfilled、onRejected呢?又或者,promise2根本就没有任何一个onFuifiied、onReject的响应函数呢?这两个问题的答案是简单而一直的:如果没有有效的响应函数,仍将产生新的promise2,并且它的resolve将以then链中当前的promise的值为值,因此完成的置值逻辑如下:
promise2 = p.then(resolved, rejected);
// 它的完整逻辑如下
try{
if (isRejected(p)) {
if(!isValidHandler(rejected)) throw result;
x2 = rejected(result);
} else {
x2 = isValidHandler(resolved) ? resolved(result):result;
}
resolve(x2)
}catch(e) {
reject(e)
}
// 检测如下
// 得到一个promise
p = Promise.resolve(100);
// 通过Then链得到promise2,但 onFulFilled、onRejected都未传入
promise2 = p.then();
// 由于没有函数来相应onFulfilled、onRejected,所以pomise2将默认使用p所代理的值
promise2.then(console.log);
// 类似的,这一置值过程也及时了将catch用作then链结尾的用法
// 得到一个rejected的promise,使用定制的对象
p = Promise.reject({message: 'REJECTED'});
// 在then链中将用到响应函数
resolved = x => x;
rejected = obj => console.log(obj.message);
// 通过then链得到promise3
promise3 = p.then(resolved).catch(rejected);
在任意场的then链中,如果链的前端出现了rejected值,无论经过多少级,then()响应,最终在rejected值都能持续向后传递并被‘链尾的catch’响应到。这也带来了promise机制的js中应用的第一原则。 始于promise,终于 catch。
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!