为了账号安全,请及时绑定邮箱和手机立即绑定

承诺不仅仅是回调吗?

承诺不仅仅是回调吗?

慕斯709654 2019-05-25 17:04:37
承诺不仅仅是回调吗?我已经开发了几年的JavaScript,我根本不理解有关承诺的大惊小怪。似乎我所做的只是改变:api(function(result){     api2(function(result2){         api3(function(result3){              // do work         });     });});无论如何,我可以使用像async这样的库,例如:api().then(function(result){      api2().then(function(result2){           api3().then(function(result3){                // do work           });      });});哪个代码更多,可读性更低。我没有在这里获得任何东西,它也不会突然神奇地“平坦”。更不用说必须将事物转换为承诺。那么,这里的承诺有什么大惊小怪?
查看完整描述

4 回答

?
万千封印

TA贡献1891条经验 获得超3个赞

承诺不是回调。promise表示异步操作未来结果。当然,按照你的方式写它们,你得到的好处不大。但是如果按照它们的使用方式编写它们,您可以以类似于同步代码的方式编写异步代码,并且更容易遵循:

api().then(function(result){
    return api2();}).then(function(result2){
    return api3();}).then(function(result3){
     // do work});

当然,代码不多,但更具可读性。

但这不是结束。让我们发现真正的好处:如果您想检查任何步骤中的任何错误怎么办?用回调来做这件事就好了,但有了承诺,这是小菜一碟:

api().then(function(result){
    return api2();}).then(function(result2){
    return api3();}).then(function(result3){
     // do work}).catch(function(error) {
     //handle any error that may occur before this point});

几乎和try { ... } catch块一样。

更好的是:

api().then(function(result){
    return api2();}).then(function(result2){
    return api3();}).then(function(result3){
     // do work}).catch(function(error) {
     //handle any error that may occur before this point}).then(function() {
     //do something whether there was an error or not
     //like hiding an spinner if you were performing an AJAX request.});

更妙的是:如果这3个调用apiapi2api3可以同时运行(例如,如果他们是AJAX调用),但你需要等待三个?没有承诺,你应该创建某种计数器。承诺,使用ES6符号,是另一块蛋糕,非常整洁:

Promise.all([api(), api2(), api3()]).then(function(result) {
    //do work. result is an array contains the values of the three fulfilled promises.}).catch(function(error) {
    //handle the error. At least one of the promises rejected.});

希望你现在以新的眼光看待Promise。


查看完整回答
反对 回复 2019-05-25
?
牛魔王的故事

TA贡献1830条经验 获得超3个赞

除了已经建立的答案之外,凭借ES6箭头功能,Promise从一个中等闪亮的小蓝矮星直接变成一个红色巨人。那即将崩溃成超新星:

api().then(result => api2()).then(result2 => api3()).then(result3 => console.log(result3))

正如oligofren指出的那样,在api调用之间没有参数,你根本不需要匿名包装器函数:

api().then(api2).then(api3).then(r3 => console.log(r3))

最后,如果你想达到一个超大质量的黑洞水平,可以期待Promises:

async function callApis() {
    let api1Result = await api();
    let api2Result = await api2(api1Result);
    let api3Result = await api3(api2Result);

    return api3Result;}


查看完整回答
反对 回复 2019-05-25
?
繁花如伊

TA贡献2012条经验 获得超12个赞

除了其他答案之外,ES2015语法与promises无缝融合,减少了更多的样板代码:

// Sequentially:api1()
  .then(r1 => api2(r1))
  .then(r2 => api3(r2))
  .then(r3 => {
      // Done
  });// Parallel:Promise.all([
    api1(),
    api2(),
    api3()]).then(([r1, r2, r3]) => {
    // Done});


查看完整回答
反对 回复 2019-05-25
  • 4 回答
  • 0 关注
  • 366 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信