【火车购票源码】【手游平台程序源码网站】【小程序用啥源码登录】es6 promise 源码

来源:源码编辑器画三个圆圈教程

1.从规范面解读:Promises/A+规范与浏览器Promise规范有何区别?
2.利用ES6的Promise.all实现至少请求多长时间的实例
3.JS的Promise兄弟

es6 promise 源码

从规范面解读:Promises/A+规范与浏览器Promise规范有何区别?

       前言

       Promise是一种优秀的异步解决方案,其原生实现更是面试中的爆点,提到Promise实现,我们首先会想起Promises/A+规范,大多数教程中都是按照Promises/A+规范来实现Promise。

       小包也是火车购票源码Promises/A+圣经的执行者之一,但小包心中一直有个好奇,遵循Promises/A+规范实现的Promise与ES6-Promise能有什么区别呐?

       文章中的测试代码选取小包基于Promises/A+规范实现的原生Promise

       学习本文,你能收获:

       进一步完善原生Promise的实现

       更进一步理解Promise与microTask之间的关系

promise的成功值value

       Promises/A+规范只提供了value的定义,并没有详细说明如何处理不同类型的value值:

       “value”isanylegalJavaScriptvalue(including?undefined,athenable,orapromise).value可以是任意合法的JavaScript值,包括undefined、具备then接口的对象或者promise

       但ECMAScript规范对不同类型的value做了细致的处理。

       红框部分我们可以看出,ES6规范会根据resolution(相当于Promises/A+规范中的手游平台程序源码网站value)类型选取不同的执行方案。

       判断resolution是否为Object,如果不是,直接执行FulfillPromise

       如果是Object,试探是否存在then接口

       判断then是否可执行(abruptcompletion可以理解为非正常值)

       如果then可执行,将then方法放入事件队列中。

       PromiseResolveThenableJob:该job使用传入的thenable的then方法来解决promise。

       一句话总结上面的过程:如果value值为可thenable对象或者promise,ES6会采用该thenable的状态。

       小包举个栗子:

const?p?=?new?Promise((resolve)?=>?{ resolve(1);});const?p1?=?new?Promise((resolve)?=>?{ resolve(p);});p1.then((d)?=>?console.log(d));

       p1接收的成功值value为Promisep,p状态为fulfilled,这种情况下ES6中会采取p的状态及value,因此最终打印1。

       我们将p更换为具备thenable对象,小程序用啥源码登录结果也是类似的。

//?类?promise?对象const?p1?=?{ a:?1,then(onFulfilled,?onReject)?{ onFulfilled(this.a);},};const?p2?=?new?Promise((resolve)?=>?{ resolve(p1);});//?1p2.then((d)?=>?console.log(d));

       Promises/A+没有对此进行规范,因此当传入的value为thenable对象时,会原封不动的输出。

       那我们应该如何完善这部分代码呐?我们需要对value值进行解析,如果value可thenable,则采纳他的状态和值,递归进行上述步骤,直至value不可thenable。(这里与resolvePromise部分递归解析onFulfilled函数的返回值是类似的)

const?resolve?=?(value)?=>?{ if?(typeof?value?===?"object"?&&?value?!=?null)?{ try?{ const?then?=?value.then;if?(typeof?then?===?"function")?{ return?then.call(value,?resolve,?reject);}}?catch?(e)?{ return?reject(e);}}if?(this.status?===?PENDING)?{ this.value?=?value;this.status?=?FULFILLED;this.onFulfilledCallbacks.forEach((cb)?=>?cb(this.value));}};Promise与microTask

       Promises/A+规范中其实并没有将Promise对象与microTask挂钩,规范是这么说的:

       Here“platformcode”meansengine,environment,andpromiseimplementationcode.Inpractice,thisrequirementensuresthat?onFulfilled?and?onRejected?executeasynchronously,aftertheeventloopturninwhich?then?iscalled,andwithafreshstack.Thiscanbeimplementedwitheithera“macro-task”mechanismsuchas?setTimeout?or?setImmediate,orwitha“micro-task”mechanismsuchas?MutationObserver?or?process.nextTick.Sincethepromiseimplementationisconsideredplatformcode,itmayitselfcontainatask-schedulingqueueor“trampoline”inwhichthehandlersarecalled.

       Promises/A+规范中表示then方法可以通过setTimeout或setImediate等宏任务机制实现,也可以通过MutationObserver或process.nextTick等微任务机制实现。

       但经过大量面试题洗礼的学校竞赛系统源码下载不了我们知道浏览器中的Promise.then典型的微任务。既然都学到这里了,小包索性就打破砂锅问到底,找到Promise与microTask挂钩的根源。

谁规定了Promise是microTask

       标准读起来属实有些无聊,但好在小包找到了最终的答案。

       首先小包先入为主的以为,Promise的详细规定应该都位于ECMAScript制定的规范中,但当小包进入标准后,全局搜索micro,竟然只搜索到三个Microsoft。讲实话,小包是震惊的,ECMAScript并没有规定Promise是在线文档管理系统源码下载microTask。

       ECMAScript规范中,最接近的是下面两段表达:

       The?host-defined?abstractoperationHostEnqueuePromiseJobtakesarguments?job?(a?Job?AbstractClosure)and?realm?(a?RealmRecord?or?null)andreturns?unused.Itschedules?job?tobeperformedatsomefuturetime.The?AbstractClosures?usedwiththisalgorithmareintendedtoberelatedtothehandlingofPromises,orotherwise,tobescheduledwithequalprioritytoPromisehandlingoperations.

       JobsarescheduledforexecutionbyECMAScripthostenvironments.ThisspecificationdescribesthehosthookHostEnqueuePromiseJobtoscheduleonekindofjob;hostsmaydefineadditionalabstractoperationswhichschedulejobs.SuchoperationsacceptaJobAbstractClosureastheparameterandscheduleittobeperformedatsomefuturetime.Theirimplementationsmustconformtothefollowingrequirements:

       上面两句话意思大约是:ECMAScript中将Promise看作一个job(作业),HostEnqueuePromiseJob是用来调度Promise作业的方法,这个方法会在未来某个时间段执行,具体执行与Promise的处理函数或者与Promise处理操作相同的优先级有关。

       那何处将Promise规定为microTask呐?---HTML标准

       HTML标准中指出:

       JavaScriptcontainsan?implementation-defined?HostEnqueuePromiseJob(job,?realm)abstractoperationtoschedulePromise-relatedoperations.HTMLschedulestheseoperationsinthemicrotaskqueue.

       上述标准的最后一句话指出,HTML将在microqueue中安排这些操作。破案了,原来是HTML标准中将Promise规定为microTask。(为什么会是HTML进行规定,小包还没有探究出来)

       更深入的区别,请参考月夕大佬:V8Promise源码全面解读

后语

       我是?战场小包?,一个快速成长中的小前端,希望可以和大家一起进步。

       如果喜欢小包,可以在?掘金?关注我,同样也可以关注我的小小公众号——小包学前端。

       一路加油,冲向未来!!!

疫情早日结束人间恢复太平

       原文:/post/

利用ES6的Promise.all实现至少请求多长时间的实例

        1、背景

       我们都知道ajax请求可以加个timeout,就是最多请求多少时间,如果超过这个时间直接就报错。 这个是最多请求多长时间,我现在要做的是,最少要请求多长时间,然后才能执行后续的逻辑。

       比如,一个ajax请求 x 毫秒就执行完毕了,但我要让他至少执行1秒钟,那我们会这么想: ajax完成后 , 1. 如果x<1s, 那我们先setTimeout => 1s - x ,然后执行后续操作。 2 如果x>=1s, 那我们直接执行后续操作。 想想这可繁琐了,我们还要在前面记录一下开始时间,后面记录一下结束时间,然后才能得到x。。

       或者变量flag,ajax里面完成设置flag,setTimeout里面完成也设置flag等等等方法,都很繁琐、

       2、Solution

       现在ES6有个Promise.all,非常适合解决此类问题。直接这样 Promise.all([ajaxPromise(), waitPromise(1s)]).then(()=> 至少执行了1s) 。。

       如果说是 多个ajax(promise)按顺序执行,但总共加起来的时间至少是1s呢? 那就用一个Promise把多个ajax包起来。然后 Promise.all([ajaxPromiseAll(), waitPromise(1s)]).then(()=> 至少执行了1s) 。。

       3、 讲得很抽象,实例为证

       这个实例是这样的,微信里面有拆红包,当我们点击 _ 的时候,那个字至少会完整的 翻一翻。那个完整翻一翻的时间我们假定需要1秒钟。 如果我们直接点击开的时候,立即请求ajax,等ajax完成立即拆开红包,这里的时间 有可能不足1s,那 就不能做到完整翻一翻。 如果请求大于1s,那就让它一直翻转吧,直到完成请求。所以我们为了解决这个问题,就需要用到上面的技术。

       参考代码如下(Chrome最新版下测试):

       / ajax模拟A

       const funcA = async () =>

        new Promise(resovel => {

        setTimeout(() => {

        console.log("done A");

        resovel("func A");

        }, );

        });

       因为async和await使用起来比Promise爽,所以我采用了这两个语法糖来写,用setTimeout来模拟ajax请求, ajax模拟A和 ajax模拟B有顺序关系的,比如先检测这个人是否还有机会打开红包,然后再请求打开红包获得随机红包金额 。

       以上这篇利用ES6的Promise.all实现至少请求多长时间的实例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。

JS的Promise兄弟

          相信用过JS的都知道JS是单线程的,同步的函数先执行,异步的函数先加入到一个队列中等同步执行完了再执行异步函数。基于这个JS采用异步回调的方式来处理需要等待的事件,是的代码会继续执行而不用在异步处理的地方一直等待着。同时也带来一个不好的方面,如果我们有很多的回调函数, 也就是说一个回调函数里边再嵌套一个回调一层一层的嵌套,这样就很容易进入传说中的回调地狱。

           注意:异步和回调不是一个东西

          下面感受一下回调地狱代码的魅力:

          是挺有美感的但是阅读性很差,写法也让人感到无力,es6新出的promise对象已经es7的async await都可以解决这个问题,但是今天的主角是Promise。

          Promise是异步编程的一种解决方案,可以替代传统的解决方案--回调函数和事件。ES6统一了用法,并原生提供了Promise对象。作为对象,Promise有一下两个特点:(1)对象的状态不受外界影响;(2)一旦状态改变了就不会在变,也就是说任何时候Promise都只有一种状态。Promise有三种状态,分别是:Pending(进行中),Resolved(完成),Rejected (失败)。Promise从Pending状态开始,如果成功就转到成功态,并执行resolve回调函数;如果失败就转到失败状态并执行reject回调函数。

          Promise一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise 对象的状态改变,只有两种可能:从 Pending 变为 Resolved 和从 Pending 变为 Rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果。就算改变已经发生了,你再对 Promise 对象添加回调函数,也会立即得到这个结果。这与事件(Event)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的。

          Promise构造函数接收一个函数作为参数,该函数的两个参数是resolve,reject,它们由JavaScript引擎提供。其中resolve函数的作用是当Promise对象转移到成功,调用resolve并将操作结果作为其参数传递出去;reject函数的作用是单Promise对象的状态变为失败时,将操作报出的错误作为其参数传递出去

          介绍一下Promise的api怎么使用:

           1、Promise.resolve()的作用将现有对象转为Promise对象resolved;Promise.resolve('test')==new Promise(resolve=>resolve('test'))

          2、Promise.reject()返回一个Promise对象,状态为rejected

          3、Promise.prototype.then()方法接受两个参数,第一个是成功的resolved的回调,另一个是失败rejected的回调,第二个失败的回调参数可选。并且then方法里也可以返回promise对象,这样就可以链式调用了。

           4、Promise.prototype.catch()发生错误的回调函数。

           5、Promise.all() // 所有的事都有完成,相当于 且,适合用于所有的结果都完成了才去执行then()成功的操作。

           6、Promise.race() // 完成一个任务即可,相当于 或。(这个经常用在一些图片比较多的网站)

文章所属分类:综合频道,点击进入>>