zoukankan      html  css  js  c++  java
  • 如何使用Promise

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

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

     1 // 就像下面这样:
     2 // 你不在乎下面这三个ajax的执行顺序还好
     3 // 如果你在乎顺序呢?
     4 $.get('url', function(){
     5     
     6 }, 'json');
     7 $.get('url1', function(){
     8     
     9 }, 'json');
    10 $.get('url2', function(){
    11     
    12 }, 'json');
    13 
    14 // 就像这样?
    15 $.get('url', function(){
    16     $.get('url1', function(){
    17         $.get('url2', function(){
    18     
    19         }, 'json');
    20     }, 'json');
    21 }, 'json');
    22 
    23 
    24 // 下面是我最近写的一段Node.js的代码
    25 // 其实这个嵌套也不算多
    26 // 如果业务逻辑相当复杂起来呢?
    27 // 嵌套20 30层?
    28 var adminIndex = function(params, callback){
    29   storeAdmin.getApiTokens(function(err, tokens){
    30     if ( err ) { callback(err); return; }
    31     storeAdmin.getApiServices(function(err, apiServices){
    32       if ( err ) { callback(err); return; }
    33       storeAdmin.getSocketioServices(function(err, socketioServices){
    34         if ( err ) { callback(err); return; }
    35         callback(0, {
    36           status : true,
    37           data : {
    38             api_tokens : tokens,
    39             api_services : apiServices,
    40             socketio_services : socketioServices
    41           }
    42         });
    43       });
    44     });
    45   });
    46 };

    说了这么多,到底什么是Promise呢?

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

    那Promise怎么用呢?

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

     1 var val = 1;
     2 
     3 // 我们假设step1, step2, step3都是ajax调用后端或者是
     4 // 在Node.js上查询数据库的异步操作
     5 // 每个步骤都有对应的失败和成功处理回调
     6 // 需求是这样,step1、step2、step3必须按顺序执行
     7 function step1(resolve, reject) {
     8     console.log('步骤一:执行');
     9     if (val >= 1) {
    10         resolve('Hello I am No.1');
    11     } else if (val === 0) {
    12         reject(val);
    13     }
    14 }
    15 
    16 function step2(resolve, reject) {
    17     console.log('步骤二:执行');
    18     if (val === 1) {
    19         resolve('Hello I am No.2');
    20     } else if (val === 0) {
    21         reject(val);
    22     }
    23 }
    24 
    25 function step3(resolve, reject) {
    26     console.log('步骤三:执行');
    27     if (val === 1) {
    28         resolve('Hello I am No.3');
    29     } else if (val === 0) {
    30         reject(val);
    31     }
    32 }
    33 
    34 new Promise(step1).then(function(val){
    35     console.info(val);
    36     return new Promise(step2);
    37 }).then(function(val){
    38     console.info(val);
    39     return new Promise(step3);
    40 }).then(function(val){
    41     console.info(val);
    42     return val;
    43 }).then(function(val){
    44     console.info(val);
    45     return val;
    46 });
    47 
    48 // 执行之后将会打印
    49 步骤一:执行
    50 Hello I am No.1
    51 步骤二:执行
    52 Hello I am No.2
    53 步骤三:执行
    54 Hello I am No.3
    55 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方法参数中。

  • 相关阅读:
    Digital image processing In C#
    C#数字图像处理(摘录)
    C# P/Invoke中传递数组参数
    字符常用方法(c#)——(待扩展)
    java监控多个线程的实现
    jdbc访问数据库
    java与MSSQL2000连接
    java下的日期函数实现
    MyEclipse中防止代码格式化时出现换行的情况的设置
    java InputStream读取数据问题
  • 原文地址:https://www.cnblogs.com/jiechen/p/5585361.html
Copyright © 2011-2022 走看看