最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • Promise的核心机制

    正文概述 掘金(BXG)   2021-06-13   420

    一般情况下,用户代码主要用两种方法得到一个promise对象:

    1. 使用 new Promise来创建一个promise;

    2. 使用类方法 Promise.xxx()--包括resolve(),reject,all或者race等来获得一个promise;

    任何方法得到的promise对象都具有then、catch等方法,也称为 promise.prototype.xxx()原型方法。
    javascript约定调用这些方法讲‘绝对’不会跑出异常,而这也是得到一个新的promise对象的第三种方法:

    1. 使用原型方法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可能会被置入两种值之一,这两种值是指:

    1. 如果promise被成功resolve,则该值为有效值(value)。
    2. 如果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。


    起源地下载网 » Promise的核心机制

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元