资讯专栏INFORMATION COLUMN

JavaScript Promise 告别异步乱嵌套

Ryan_Li / 2504人阅读

摘要:回调函数少了还好,一旦多了起来而且必须讲究执行顺序的话,回调函数开始嵌套,那代码的恶心程度是相当不符合常人的线性思维的。

这是我的原创文章,原文地址:http://lpgray.me/article/43/

什么是Promise? 在说Promise之前,不得不说一下JavaScript的嵌套的回调函数

在JavaScript语言中,无论是写浏览器端的各种事件处理回调、ajax回调,还是写Node.js上的业务逻辑,不得不面对的问题就是各种回调函数。回调函数少了还好,一旦多了起来而且必须讲究执行顺序的话,回调函数开始嵌套,那代码的恶心程度是相当不符合常人的线性思维的。

说到这里,我真有点想去了解一下响马老师的fibjs,我没有接触过它,但它的编程方式就是线性的,更加符合常人思维。我个人认为Promise就是为了把JS复杂的嵌套转换成常人思维的线性代码。

// 就像下面这样:
// 你不在乎下面这三个ajax的执行顺序还好
// 如果你在乎顺序呢?
$.get("url", function(){
    
}, "json");
$.get("url1", function(){
    
}, "json");
$.get("url2", function(){
    
}, "json");

// 就像这样?
$.get("url", function(){
    $.get("url1", function(){
        $.get("url2", function(){
    
        }, "json");
    }, "json");
}, "json");


// 下面是我最近写的一段Node.js的代码
// 其实这个嵌套也不算多
// 如果业务逻辑相当复杂起来呢?
// 嵌套20 30层?
var adminIndex = function(params, callback){
  storeAdmin.getApiTokens(function(err, tokens){
    if ( err ) { callback(err); return; }
    storeAdmin.getApiServices(function(err, apiServices){
      if ( err ) { callback(err); return; }
      storeAdmin.getSocketioServices(function(err, socketioServices){
        if ( err ) { callback(err); return; }
        callback(0, {
          status : true,
          data : {
            api_tokens : tokens,
            api_services : apiServices,
            socketio_services : socketioServices
          }
        });
      });
    });
  });
};
说了这么多,到底什么是Promise呢?

其实,Promise就是一个类,而且这个类已经成为了ES6的标准,这个类目前在chrome32、Opera19、Firefox29以上的版本都已经支持了,要想在所有浏览器上都用上的话就看看es6-promise吧。

那Promise怎么用呢?

看一段很简单的代码,请注意阅读代码中的注释。

var val = 1;

// 我们假设step1, step2, step3都是ajax调用后端或者是
// 在Node.js上查询数据库的异步操作
// 每个步骤都有对应的失败和成功处理回调
// 需求是这样,step1、step2、step3必须按顺序执行
function step1(resolve, reject) {
    console.log("步骤一:执行");
    if (val >= 1) {
        resolve("Hello I am No.1");
    } else if (val === 0) {
        reject(val);
    }
}

function step2(resolve, reject) {
    console.log("步骤二:执行");
    if (val === 1) {
        resolve("Hello I am No.2");
    } else if (val === 0) {
        reject(val);
    }
}

function step3(resolve, reject) {
    console.log("步骤三:执行");
    if (val === 1) {
        resolve("Hello I am No.3");
    } else if (val === 0) {
        reject(val);
    }
}

new Promise(step1).then(function(val){
    console.info(val);
    return new Promise(step2);
}).then(function(val){
    console.info(val);
    return new Promise(step3);
}).then(function(val){
    console.info(val);
    return val;
}).then(function(val){
    console.info(val);
    return val;
});

// 执行之后将会打印
步骤一:执行
Hello I am No.1
步骤二:执行
Hello I am No.2
步骤三:执行
Hello I am No.3
Hello I am No.3
Promise到底解决什么问题?

正如上面代码所示,笔者认为,Promise的意义就在于 then 链式调用 ,它避免了异步函数之间的层层嵌套,将原来异步函数的 嵌套关系 转变为便于阅读和理解的 链式步骤关系

Promise的主要用法就是将各个异步操作封装成好多Promise,而一个Promise只处理一个异步逻辑。最后将各个Promise用链式调用写法串联,在这样处理下,如果异步逻辑之间前后关系很重的话,你也不需要层层嵌套,只需要把每个异步逻辑封装成Promise链式调用就可以了。

Promise常用的关键点 在Promise定义时,函数已经执行了

Promise构造函数只接受一个参数,即带有异步逻辑的函数。这个函数在 new Promise 时已经执行了。只不过在没有调用 then 之前不会 resolve 或 reject。

在then中的resolve方法中如何return?

在then方法中通常传递两个参数,一个 resolve 函数,一个 reject 函数。reject暂时不讨论,就是出错的时候运行的函数罢了。resolve 函数必须返回一个值才能把链式调用进行下去,而且这个值返回什么是有很大讲究的。

resolve 返回一个新 Promise

返回一个新Promise之后再调用的then就是新Promise中的逻辑了。

resolve 返回一个值

返回一个值会传递到下一个then的resolve方法参数中。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/85411.html

相关文章

  • JavaScript Promise 告别异步嵌套

    摘要:回调函数少了还好,一旦多了起来而且必须讲究执行顺序的话,回调函数开始嵌套,那代码的恶心程度是相当不符合常人的线性思维的。 什么是Promise? 在说Promise之前, 不得不说一下,JavaScript的嵌套的回调函数 在JavaScript语言中, 无论是写浏览器端的各种事件回调、ajax回调,还是写Node.js上的业务逻辑,不得不面对的问题就是各种回调函数。回调函数少了还好,...

    Mr_houzi 评论0 收藏0
  • 终极蛇皮上帝视角之微信小程序之告别 setData

    摘要:而小程序官方的是在中调用方法来改变数据,从而改变界面。为了写测试让咱们来重构一把,利用学习过的函数式编程中的高阶函数把依赖注入。也就是说当中的某个数据更新的时候,我们并不知道它会影响哪个中的属性,特别的还有依赖于的情况。 众所周知 Vue 是借助 ES5 的 Object.defineProperty 方法设置 getter、setter 达到数据驱动界面,当然其中还有模板编译等等其他...

    wuyumin 评论0 收藏0
  • Async/Await替代Promise的6个理由

    摘要:是基于实现的,它不能用于普通的回调函数。忧虑对于,也许你有一些合理的怀疑它使得异步代码不再明显我们已经习惯了用回调函数或者来识别异步代码,我们可能需要花数个星期去习惯新的标志。 译者按: Node.js的异步编程方式有效提高了应用性能;然而回调地狱却让人望而生畏,Promise让我们告别回调函数,写出更优雅的异步代码;在实践过程中,却发现Promise并不完美;技术进步是无止境的,这时...

    tuomao 评论0 收藏0
  • ES6-7

    摘要:的翻译文档由的维护很多人说,阮老师已经有一本关于的书了入门,觉得看看这本书就足够了。前端的异步解决方案之和异步编程模式在前端开发过程中,显得越来越重要。为了让编程更美好,我们就需要引入来降低异步编程的复杂性。 JavaScript Promise 迷你书(中文版) 超详细介绍promise的gitbook,看完再不会promise...... 本书的目的是以目前还在制定中的ECMASc...

    mudiyouyou 评论0 收藏0
  • 异步解决方案----Promise与Await

    摘要:前言异步编程模式在前端开发过程中,显得越来越重要。随着新标准的到来,处理异步数据流又有了新的方案。接下来我们介绍这两种处理异步编程的方案。仍在继续执行,但执行结果将被丢弃。使得异步代码看起来像同步代码,再也没有回调函数。 前言 异步编程模式在前端开发过程中,显得越来越重要。从最开始的XHR到封装后的Ajax都在试图解决异步编程过程中的问题。随着ES6新标准的到来,处理异步数据流又有了新...

    Blackjun 评论0 收藏0

发表评论

0条评论

Ryan_Li

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<