自定义的Promise

1、准备知识


1、回调函数:

理解:一个函数,自己定义的,自己没有调用,但是函数执行了。

同步回调:立即执行,完全执行完才结束,不会放到回调队列中

 例子: 数组遍历的forEach()还有promise的excutor

异步回调:不会被立即执行,会被放到回调函数中将来执行

例子:定时器回调、ajax回调、promise的成功回调onResolve和失败回调onReject

 2、错误类型

*Error:所有错误的父类型

ReferenceError:引用变量不存在,打印一个未声明的变量会触发此错误

TypeError:数据类型不正确,将一个一般类型的变量当成函数调用会触发此错误

RangerError:数据值不在允许的方范围,一个递归没有跳出条件,递归会不断执行最后将栈占满

SyntaxError:语法错误

*错误处理

捕获错误:try...catch()   使代码不会因为报错而停止执行

抛出错误:throw error 抛出的错误可以用try...catch()来接收

2、Promise

1、promise是什么:

promise是js中进行异步编程的新的解决方案

具体表达:

从语法上来说:promise是一个构造函数

从功能上说:promise对象用来封装一个异步操作并可以获取其结果

2、promise状态:

pedding:初始状态

resolve:成功状态

reject:失败状态

3、promise状态的改变:

pending变为resolved

pending变为rejected

说明 : 只有这两种,且一个promise对象只能改变一次

无论成功还是失败,都只会由一个数据结果

成功的结果数据一般称为value,失败的结果一般成为reason

4、promise包含的内容:

promise构造函数:Promise(excutor{})

excutor函数:同步执行(resolve,reject)=>{}

resolve函数:内部定义成功时我们调用的函数 value=>{}

reject函数:内部定义失败时我们调用的函数 reason=>{}

说明:excutor会在promise内部立即同步回调,异步操作在执行器中执行

4、promise的基本使用:

Promise是一个构造函数,构造函数的参数是一个函数即excutor(同步函数),该函数用来修改promise的状态可以是pedding->resolve成功,pedding->reject失败。然后可以执行.then()函数用来处理成功或者失败的回调

5、promise的好处

1、指定回调函数的方式更加灵活:

旧的:必须在启动异步任务前指定

 promise: 启动异步任务==>返回promise对象=>给psomise对象绑定回调函数(甚至可以在异步任务执行结束后指定)

2、支持链式调用 可以很好地解决回调地狱问题

什么是回调地狱:回调函数的嵌套调用,外部回调函数异步执行的结果是嵌套回调函数执行的条件

回调地狱的缺点:不便于阅读/不便于异步处理

6、Promise的基本方法

1、promise.prototype.then方法:(onResolved,onRejected)=>{}

onResolved函数:成功的回调函数(value)=>{}

onRjected函数:失败的回调函数(reason)=>{}

说明:指定用于得到成功的value的成功回调和用于得到失败的reason的失败回调

返回一个新的promise对象

2、promise.prototype.catch方法:(onRejected)=>{}

onRejected函数:失败的回调函数(reason)=>{}

说明:相当于then(undefined,onRejected)

3、promise.resolve方法:(value)=>{}

value:成功的数据或promise对象

说明:返回一个成功/失败的promise对象

 4、promise.reject方法:(reason)=>{}

 value:失败的原因

 说明:返回失败的promise对象

5、promise.all()方法:(promises)=>{}

promises:包含n个promise的数组

说明:返回一个新的promise,只有所有的Prmise成功才成功,只要有一个失败就直接失败

6、promise.race()方法:(promises)=>{}

promises:包含n个promise的数组

说明:返回一个新的promise,第一个完成promise的结果状态就是最终的结果

6、自定义promise之前的几个关键问题

1、promise的状态如何改变

resolve(value):如果当前是pedding就会变成resolve

reject(reason):如果当前是pedding那么就会变成reject

抛出异常:如果当前是pedding就会变为reject

2、改变promise状态和指定回调函数谁先谁后

(1)都有可能,正常情况下是先指定回调函数在改变状态,但是可以先改变状态在指定回调

(2)如何先改变状态在指定回调

     在执行器中调用resolve()/reject()

      延迟更长时间再调用then()

(3)什么时候才能得到数据

     如果先指定回调函数,那么在状态方法改变时,回调函数就会调用,得到数据

      如果先改变状态,那么当指定回调时,回调函数就会调用,得到数据

3、关于promise的then方法返回promise对象的状态

promise.then()返回的新promise的结果状态由什么决定?

(1)简单表达:由then()指定的回调函数执行的结果决定

(2)详细表达:

*如果抛出异常:新的promise变为rejected,reason为抛出的异常 

*如果返回的是一个非promise的任意值,新promise变为resolved,value为返回的值,如果没有返回结果那么相当于return undefined 

*如果返回的是另一个新的promise,此时promise的结果就会成为新的promise的结果

4、promise如何进行串联的多个任务操作

(1)promise的then()返回一个新的promise,可以实现then的链式调用

(2)通过then的链式调用串联多个同步/异步任务

5、promise异常穿透

(1)当使用promise的then链式调用时,可以在最后面指定失败的回调

(2)前面任何操作出了异常,都会传到最后失败的回调中去

中断promise链

(1)当使用promise的then链式调用时,在中间中断,不在调用后面的回调函数

(2)办法:在回调函数中返回一个pendding状态的promise对象

7、自定义的promise

1、promsie是一个构造函数并且接受一个函数(excutor)作为参数,这个函数是同步执行的,该函数又接收两个函数作为参数resolve(),reject()。代码实现:

2、一个promise应该有的数据:状态(pedding,resolve,reject),传递的数据,用于存储then中的回调函数的数组。为什么要设置这个数组,因为我们前面讨论过promise修改状态和指定回调函数顺序的问题(问题2),如果先指定回调函数在修改状态那么此时应该将回调函数存储起来,以便修改过状态之后直接调用。代码实现:

3、resolve和reject函数所做的工作:修改状态(只修改一次),将传递的数据保存,如果回调函数已经指定那么执行回调函数。代码实现:

4、如果promise抛出一个错误那么他将会执行reject函数,即问题1的第三点,代码实现:

5、then函数执行以下几种情况需要考虑:状态是否已经发生改变,如果改变直接执行onResolved函数,如果没有改变那么将onResolved函数和onRejected函数压入callback数组中,代码实现:

6、关于promise的then方法返回promise对象的状态即问题3,如果回调函数返回是promise,那么return的那个promise结果就是要向下传递的结果。这种情况在原装的promise中是以return new promise.resolve(value)的形态呈现。

要想知道返回的是否成功必须取回promise的值,因此用then的方法来获取promise的值以及状态

 如果成功说明原装代码为return new promise.resolve(value),返回的下一个状态也应该是成功,所以调用resolve

 如果失败说明原装代码为return new promise.reject(reason),返回的下一个状态也应该是失败,所以调用reject

实现代码:

7、如果then函数中不指定onResolved函数,onRejected函数时,promise有默认的操作,如果是不指定onResolved函数,那么把上面的value值继续向下传递,如果不指定onRejected函数那么抛出一个错误。代码实现:

完整代码:https://github.com/wangczc1234/Promise

最后欢迎大家投递

字节跳动校招内推码: 2XVEJNC

校招投递链接: https://jobs.toutiao.com/s/djchQRf

社招投递链接: https://job.toutiao.com/s/djc2b4C

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,907评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,987评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,298评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,586评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,633评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,488评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,275评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,176评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,619评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,819评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,932评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,655评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,265评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,871评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,994评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,095评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,884评论 2 354