【JS】以下几行代码中,Promise对比回调的优势在哪里?

最近学ES6,了解到promise,可以通过then().then().then()的方式解决回调地狱
想请问:
像下边的简单逻辑情况下,两者的功效可能一样的。
那么promise还有什么优势吗?
如果有,在哪里,希望得到老司机码力加持,请不惜金码,敲上两行。
谢谢你的帮助

    function afterSomeSeconds( callBackFn ){

setTimeout(()=>{

callBackFn('2秒过去了,异步执行结束');

}, 2 * 1000);

};

afterSomeSeconds(function toLog(msg){

console.log(msg)

});

console.log('主线程1');

// ▲传统回调,

// ——————————————————————————————————————————————————————————

// ▼ES6的Promise

function afterSomeSecondsPromise(){

return new Promise(function(resolve, reject){

setTimeout(()=>{

resolve('3秒过去了,异步执行结束');

}, 3 * 1000);

})

}

afterSomeSecondsPromise().then(msg=>{

console.log(msg)

});

console.log('主线程2');

控制台打印如下:

主线程1

主线程2

2秒过去了,异步执行结束

3秒过去了,异步执行结束

回答

从本质来讲两者都能实现我们想要的功能,但真正投入开发,你会发现promise跟async/await搭配简直就是一把梭子。
利用promise跟async/await可以将异步操作改成‘伪同步’(实质还是异步),编码上思路更加顺溜了。

往往项目开发我们都会封装通用的请求函数
使用回调的封装就是

export  const Http= {

get:function(url,data,sucCb,errCb){

axios.get(url,{params:data})

.then(function(res){

if (res.data.code==200) {

//这里可以写一些请求操作成功需要统一处理的代码,例如弹框显示成功

sucCb(res.data.data)

}else {

//这里可以写一些请求操作失败需要统一处理的代码,例如弹框显示失败

errCb(res.data.message);

}

})

.catch(function(err){

//这里可以写一些请求操作失败需要统一处理的代码,例如弹框显示失败

errCb(err);

})

},

post:function(...){...},

put:function(...){...},

delete:function(...){...},

}

如何调用呢

Http.get(url,data,function(res){

//请求成功啦,做处理

},function(err){

//请求失败啦,快做处理

})

当接口很多的时候,这种反复的操作能写到你烦。
那我们使用promise封装呢?结果会是怎么样

export  const Http= {

get:function(url,data){

return new Promise((resolve,reject)=>{

axios.get(url,{params:data})

.then(function(res){

if (res.data.code==200) {

//这里可以写一些请求操作成功需要统一处理的代码,例如弹框显示成功

resolve(res.data.data)

}else {

//这里可以写一些请求操作失败需要统一处理的代码,例如弹框显示失败

errCb(res.data.message);

}

})

.catch(function(err){

//这里可以写一些请求操作失败需要统一处理的代码,例如弹框显示失败

reject(err);

})

})

},

post:function(...){...},

put:function(...){...},

delete:function(...){...},

}

如何调用呢

async getData(){

let mydata = await Http.get(url,data);

}

一看码量减少了一半不止,而且封装了通用请求函数,可以对api做统一管理,放在一个api.js里。例如

export const Orders = {

get:function(){ return Http.get("deliver/oil-orders"); },

deliver:function(){ return Http.get("deliver/oil-orders",{section:'delivering'}); },

put:function(data){ return Http.put(`deliver/oil-orders/${data.id}`,data); }

}

export const User = {

code:function(phone){ return Http.get("sms/code",{phone:phone}); },

login:function(data){ return Http.post("deliver/login",data); },

get:function(){ return Http.get("deliver/user/info",null); }

}

以后每次调用接口都是简单的‘伪同步’
let user = await User.get();
let orders = await Orders.get();

是不是更加简洁了?

有啊!

1. await 加持下更爽

在支持 await 的环境下可以直接

var msg = await afterSomeSecondsPromise();

console.log(msg);

2.和其他异步操作结合,或者自身重复调用

fetch('./api')

.then(afterSomeSecondsPromise)

.then(msg => fetch('./api', {method: 'POST', body: msg}))

.catch(err => console.error(err)); // .catch 可以捕获甚至 afterSomeSecondsPromise 里的异常

afterSomeSecondsPromise()

.then(afterSomeSecondsPromise)

.then(afterSomeSecondsPromise);

// 试试回调版本?

我补充一点 错误处理也会变优雅, 用习惯后用 throw 来做流程控制会变为常态.

区别就是
Promise 更简洁可读性好 易操作 功能更强大一点 更加主流

你这个就好像在对比 jqueryvue,reactes5es6 不是说他差 只是有更好的 当然用更好的

优势最主要的就是体现在可读性上而已,你这里的例子过于简单了,所以说明不了问题,我给你从网上找了个图:
【JS】以下几行代码中,Promise对比回调的优势在哪里?

这个图虽然有些夸张,但足够说明问题,就是当嵌套的层级多了,可读性变差、变量命名冲突等问题就会被放大,而且这只考虑了串行调用的情况,如果并行呢,请自动脑补。

再有一个问题就是,callback 的函数签名没有约束,意味着如果你愿意的话,想怎么传参就怎么传,虽然在 nodejs 有其约定俗成的签名,比如 err 是第一个参数,之后是 data 等等,但如果是在个人项目中的话,是否遵守这个规范显然取决于开发者本身了。

使用 Promise 的好处就是一定程度上解决了回调地狱带来的问题,注意这里是一定程度上噢,而不是完全解决,由于 Promise 本身的实现有规范,因此各种实现库除去定制化的功能以外,基本一定程度上保证了一致性,比如 .then 或者 .catch,这些 api 各种库都是一样的。

当然了,还有其他的异步解决方案,不过大同小异,基本上都是在可读性、可维护性、一致性上取舍,你见的多了、用的多了就知道了。

setTimeout会把你延迟执行的内容扔到下一个EventLoop里.
Promise会将你要执行的内容扔到当前EventLoop的最后.

上面回答的太多了,就是从使用上看起来更加清晰,ES7的async和await到后续使用会更加频繁

你描述都提到了用promise解决回调地狱,但你提供的代码只是一个简单的异步处理,根本就没形成地狱。你尝试写一个3秒后打印3然后过了2秒打印2然后再过过4秒打印4,然后看一下有什么区别。

你再思考一下,假如你的异步任务发生错误你该怎么处理?当然你用计时器是没有发生错误的可能的,你改用ajax,或是nodejs的io操作。

你的问题是不了解promise的使用场景,实际上promise就是为了让异步操作变得更优雅而存在的。

ES7的async和await到后续使用会更加频繁

关于回调、Promise、async/await 的博客我好像写了不少了

你是用了setTimeout这种定时器再回调,那么在传统的单线程执行过程中,如果你需要去异步的处理一些事情而不影响主线程呢!建议多了解一下异步到底是怎么回事,而不是用定时器来描述。

以上是 【JS】以下几行代码中,Promise对比回调的优势在哪里? 的全部内容, 来源链接: utcz.com/a/87214.html

回到顶部