rejected

更新时间:2022-12-31 05:39:55 阅读: 评论:0


2022年12月31日发(作者:流动负债有哪些)

Promi知识总结

本⽂⽬录:

1.什么是回调函数?回调函数有什么缺点

e是什么,可以⼿写实现⼀下吗

3.⼿写简单版的Promi

,catch,finally

5.⼿写

6.⼿写

e⾥都是微任务吗

wait和promi的区别与联系

e中⽤了什么设计模式

1.什么是回调函数?回调函数有什么缺点

回调函数是⼀段可执⾏的代码段,它作为⼀个参数传递给其他的代码,其作⽤是在需要的时候⽅便调⽤这段(回调函数)代码。

在JavaScript中函数也是对象的⼀种,同样对象可以作为参数传递给函数,因此函数也可以作为参数传递给另外⼀个函数,这个作为参数的函数

就是回调函数。

constbtnAdd=mentById('btnAdd');

ntListener('click',functionclickCallback(e){

//dosomethinguless

});

在本例中,我们等待id为btnAdd的元素中的click事件,如果它被单击,则执⾏clickCallback函数。回调函数向某些数据或事件添加⼀些功能。

回调函数有⼀个致命的弱点,就是容易写出回调地狱(Callbackhell)。假设多个事件存在依赖性:

tTimeout(()=>{

(1)

tTimeout(()=>{

(2)

tTimeout(()=>{

(3)

},3000)

},2000)

},1000)

这就是典型的回调地狱,以上代码看起来不利于阅读和维护,事件⼀旦多起来就更是乱糟糟,所以在es6中提出了Promi和async/await来解决

回调地狱的问题。当然,回调函数还存在着别的⼏个缺点,⽐如不能使⽤trycatch捕获错误,不能直接return。

e是什么,可以⼿写实现⼀下吗

Promi,翻译过来是承诺,承诺它过⼀段时间会给你⼀个结果。从编程讲Promi是异步编程的⼀种解决⽅案。下⾯是Promi在MDN的相关

说明:

Promi对象是⼀个代理对象(代理⼀个值),被代理的值在Promi对象创建时可能是未知的。它允许你为异步操作的成功和失败分别绑定相

应的处理⽅法(handlers)。这让异步⽅法可以像同步⽅法那样返回值,但并不是⽴即返回最终执⾏结果,⽽是⼀个能代表未来出现的结果的

promi对象。

⼀个Promi有以下⼏种状态:

pending:初始状态,既不是成功,也不是失败状态。

fulfilled:意味着操作成功完成。

rejected:意味着操作失败。

这个承诺⼀旦从等待状态变成为其他状态就永远不能更改状态了,也就是说⼀旦状态变为fulfilled/rejected后,就不能再次改变。可能光看概念

⼤家不理解Promi,我们举个简单的栗⼦;

假如我有个⼥朋友,下周⼀是她⽣⽇,我答应她⽣⽇给她⼀个惊喜,那么从现在开始这个承诺就进⼊等待状态,等待下周⼀的到来,然后状态改

变。如果下周⼀我如约给了⼥朋友惊喜,那么这个承诺的状态就会由pending切换为fulfilled,表⽰承诺成功兑现,⼀旦是这个结果了,就不会再

有其他结果,即状态不会在发⽣改变;反之如果当天我因为⼯作太忙加班,把这事给忘了,说好的惊喜没有兑现,状态就会由pending切换为

rejected,时间不可倒流,所以状态也不能再发⽣变化。

上⼀条我们说过Promi可以解决回调地狱的问题,没错,pending状态的Promi对象会触发fulfilled/rejected状态,⼀旦状态改

变,Promi对象的then⽅法就会被调⽤;否则就会触发catch。我们将上⼀条回调地狱的代码改写⼀下:

newPromi((resolve,reject)=>{

tTimeout(()=>{

(1)

resolve()

},1000)

}).then((res)=>{

tTimeout(()=>{

(2)

},2000)

}).then((res)=>{

tTimeout(()=>{

(3)

},3000)

}).catch((err)=>{

(err)

})

其实Promi也是存在⼀些缺点的,⽐如⽆法取消Promi,错误需要通过回调函数捕获。

3.⼿写简单版的Promi

promi⼿写实现,⾯试够⽤版:

functionmyPromi(executor){

var_this=this;

illed=[];//成功的回调

cted=[];//失败的回调

="PENDING";//状态

=undefined;//成功结果

=undefined;//失败原因

functionresolve(value){

if(_==="PENDING"){

_="FULFILLED";

_=value;

_h((fn)=>fn(value));

}

}

functionreject(reason){

if(_==="PENDING"){

_="REJECTED";

_=reason;

_h((fn)=>fn(reason));

}

}

try{

executor(resolve,reject);

}catch(e){

reject(e);

}

}

//定义链式调⽤的then⽅法

=function(onFullfilled,onRejected){

if(==="FULFILLED"){

typeofonFulfilled==="function"&&onFulfilled();

}

if(==="REJECTED"){

typeofonRejected==="function"&&onRejected();

}

if(==="PENDING"){

typeofonFulfilled==="function"&&

(onFulfilled);

typeofonRejected==="function"&&(onRejected);

}

};

varmyP=newmyPromi((resolve,reject)=>{

("执⾏");

tTimeout(()=>{

reject(3);

},1000);

});

(

(res)=>{

(res);

},

(err)=>{

(err);

}

);

,catch,finally

then⽅法的第⼀个参数是resolved状态对应的回调函数,第⼆个参数(可选)是rejected状态对应的回调函数,then⽅法返回的是⼀个新的

Promi实例.(注意,不是原来那个Promi实例),因此可以采⽤链式写法,即then⽅法后⾯再调⽤另⼀个then⽅法.

getJSON("/").then(function(json){

;

}).then(function(post){

//...

});

()⽅法是`.then(null,rejection)或.then(undefined,rejection)的别名,⽤于指定发⽣错误时的回调函数.

getJSON('/').then(function(posts){

//...

}).catch(function(error){

//处理getJSON和前⼀个回调函数运⾏时发⽣的错误

('发⽣错误!',error);

});

上⾯代码中,getJSON()⽅法返回⼀个Promi对象,如果该对象状态变为resolved,则会调⽤then()⽅法指定的回调函数;如果异步操作抛出

错误,状态就会变为rejected,就会调⽤catch()⽅法指定的回调函数,处理这个错误。另外,then()⽅法指定的回调函数,如果运⾏中抛出错

误,也会被catch()⽅法捕获。

finally()⽅法⽤于指定不管Promi对象最后状态如何,都会执⾏的操作。该⽅法是ES2018引⼊标准的。

promi

.then(result=>{···})

.catch(error=>{···})

.finally(()=>{···});

上⾯代码中,不管promi最后的状态,在执⾏完then或catch指定的回调函数以后,都会执⾏finally⽅法指定的回调函数。

finally⽅法的回调函数不接受任何参数,这意味着没有办法知道,前⾯的Promi状态到底是fulfilled还是rejected。这表明,finally⽅法⾥⾯

的操作,应该是与状态⽆关的,不依赖于Promi的执⾏结果。

5.⼿写

⽅法:当参数中的promi有⼀个失败了就直接返回失败的结果,返回第⼀个失败的结果,都成功返回所有的参数结果

思路:

返回⼀个新的promi,并遍历调⽤传⼊的promi组成的数组参数,利⽤e()⽅法获取成功执⾏的所有promi的数量和数组参

数的长度进⾏⽐对,如果长度⼩于参数,则代表有失败的结果,否则就是全部成功。

functionpromiAll(promis){

//返回⼀个promi实例

returnnewPromi((resolve,reject)=>{

//做⼀个判断参数是否是数组

if(!y(promis)){

returnreject(newTypeError('argumentsmustbeArray'))

}

letcount=0,

newValues=newArray()//接收新的结果参数建⽴⼀个伪数组

for(leti=0;i<;i++){

//运⽤promi特性只会有⼀个状态

e(promis[i])

.then(res=>{

count++

newValues[i]=res//把每次返回成功的数据添加到数组中

if(count===){//数据接收完成

resolve(newValues)

}

},rej=>reject(rej))

}

})

}

成功的时候返回的是⼀个结果数组,⽽失败的时候则返回最先被reject失败状态的值。,需要注意的是,获得的成功结果的数组⾥⾯的

数据顺序和接收到的数组顺序是⼀致的。

6.⼿写

就是赛跑的意思,意思就是说,([p1,p2,p3])⾥⾯哪个结果获得的快,就返回那个结果,不管结果本⾝是成功状态还

是失败状态。

functionpromiRace(arrays){

if(!y(arrays))

return'notArray'

returnnewPromi((resolve,reject)=>{

for(vari=0;i<;i++){

e(arrays[i]).then((value)=>{

resolve(value)

},(err)=>{reject(err)})

}

})

}

e⾥都是微任务吗

Promi中只有涉及到状态变更后才需要被执⾏的回调才算是微任务,⽐如说then、catch、finally,其他所有的代码执⾏都是宏任务(同步

执⾏)。

wait和promi的区别与联系

asyncawait和promi都是异步编程解决⽅案。

Promi的写法只是回调函数的改进,使⽤then⽅法,只是让异步任务的两段执⾏更清楚⽽已。Promi的最⼤问题是代码冗余,请求任务多

时,⼀堆的then,也使得原来的语义变得很不清楚。

async搭配await是ES7提出的,它的实现是基于Promi,通过同步⽅式的写法,使得代码更容易阅读。

async/await的优势在于处理then的调⽤链,能够更清晰准确的写出代码,并且也能优雅地解决回调地狱问题。当然也存在⼀些缺点,因为

await将异步代码改造成了同步代码,如果多个异步代码没有依赖性却使⽤了await会导致性能上的降低。

e中⽤了什么设计模式

观察者模式在软件设计中是⼀个对象,维护⼀个依赖列表,当任何状态发⽣改变⾃动通知它们。

发布-订阅模式是⼀种消息传递模式,消息的发布者(Publishers)⼀般将消息发布到特定消息中⼼,订阅者(Subscriber)可以按照⾃⼰的需求

从消息中⼼订阅信息,跟消息队列挺类似的。

观察者设计模式的代码实现

//观察者设计模式

classObrver{

constructor(){

erList=[];

}

subscribe(obrver){

(obrver)

}

notifyAll(value){

h(obrve=>obrve(value))

}

}

发布-订阅设计模式的代码实现

//发布订阅

classEventEmitter{

constructor(){

hannel={};//消息中⼼

}

//subscribe

on(event,callback){

hannel[event]?hannel[event].push(callback):hannel[event]=[callback]

}

//publish

emit(event,...args){

hannel[event]&&hannel[event].forEach(callback=>callback(...args))

}

//removeevent

remove(event){

if(hannel[event]){

hannel[event]

}

}

//onceevent

once(event,callback){

(event,(...args)=>{

callback(...args);

(event)

})

}

}

从代码中也能看出他们的区别,观察者模式不对事件进⾏分类,当有事件时,将通知所有观察者。发布-订阅设计模式对事件进⾏了分类,触发不

同的事件,将通知不同的观察者。所以可以认为后者就是前者的⼀个升级版,对通知事件做了更细粒度的划分。

发布-订阅和观察者在异步中的应⽤

观察者模式

constobrver=newObrver();

ibe(value=>{

("第⼀个观察者,接收到的值为:");

(value)

});

ibe(value=>{

("第⼆个观察者,接收到的值为");

(value)

});

le("",(err,data)=>{

All(ng())

});

发布-订阅模式

//发布-订阅

constevent=newEventEmitter();

("err",);

("data",data=>{

//dosomething

(data)

});

le("",(err,data)=>{

if(err)("err",err);

("data",ng())

});

两种设计模式在异步编程中,都是通过注册全局观察者或全局事件,然后在异步环境⾥通知所有观察者或触发特定事件来实现异步编程。

劣势也很明显,⽐如全局观察者/事件过多难以维护,事件名命冲突等等,因此Promi便诞⽣了,Promi在⼀定程度上继承了观察者和发布-订

阅设计模式的思想。

本文发布于:2022-12-31 05:39:55,感谢您对本站的认可!

本文链接:http://www.wtabcd.cn/fanwen/fan/90/64104.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

上一篇:pgr
下一篇:securitycode
标签:rejected
相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图