zoukankan      html  css  js  c++  java
  • 理解与使用Promise完成复杂异步处理流程

    文章原文连接地址:https://blog.csdn.net/qq120848369/article/details/53204435

    本文谈到的Promise是指javascript环境下的Promise,然而Promise这个功能在若干语言中均有实现,我本次会在Nodejs服务端环境下进行学习和理解。

    Promise是为了解决日趋复杂的异步程序设计而出现的,简单的异步例如:发起一个ajax请求来获取数据,之后渲染DOM。

    然而现实世界并没有这么简单,我们极有可能需要同时发起多个ajax请求并等待它们全部返回,在获得结果后可能又需要根据上一轮的数据发起下一轮的ajax获取其他数据,这样的流程完全可以演变得交织错杂,编程和维护起来是非常头疼的。

    此前,我们解决这种问题就是callback的回调思路,callback嵌套callback的代码层出不穷,想追加点功能需要一层一层的数括号,这就急需一个替代方案的出现。

    new Promise(function(resolve,reject){
    	resolve();
    })
    .then(data => {
        // promise start
        console.log('result of start: ', data);
        return Promise.resolve(1); // p1
      })
      .then(data => {
        // promise p1
        console.log('result of p1: ', data);
        return Promise.reject(2); // p2
      })
      .then(data => {
        // promise p2
        console.log('result of p2: ', data);
        return Promise.resolve(3); // p3
      })
      .catch(ex => {
        // promise p3
        console.log('ex: ', ex);
        return Promise.resolve(4); // p4
      })
      .then(data => {
        // promise p4
        console.log('result of p4: ', data);
      });
    
    result of start:  start
    result of p1:  1
    ex:  2
    result of p4:  4
    

     

    终止链式: 

    终止链式:
    new Promise(function(resolve,reject){
    	resolve();
    })
    .then(data => {
        // promise start
        console.log('result of start: ', data);
        return Promise.resolve(1); // p1
      })
      .then(data => {
        // promise p1
        console.log('result of p1: ', data);
        return Promise.reject({  //终止链式
          notRealPromiseException: true,
        }); // p2
      })
      .then(data => {
        // promise p2
        console.log('result of p2: ', data);
        return Promise.resolve(3); // p3
      })
      .catch(ex => {
        // promise p3
        console.log('ex: ', ex);
        if (ex.notRealPromiseException) {
          // 一切正常,只是通过 catch 方法来中止 promise chain
          // 也就是中止 promise p2 的执行
          return true;
        }
        // 真正发生异常
        return false;
      })
    

      

    new Promise( /* executor */ function(resolve, reject) { ... } );
    这个函数提供了2个function给业务调用,调用Resolve就可以改变这个Promise的状态为resolved,同样道理调用reject就可以让Promise的状态变为rejected。

    // 同步reject
    var promise2 = new Promise(
        (resolve, reject) => {
            reject("this is promise2 reject");
        }
    ).then(
        (msg) => {
            console.log(msg);
        },
        (err) => {
            console.log(err);
        }
    );
    // 链式resolve
    var promise5 = new Promise(
        (resolve, reject) => {
            var promise4_1 = new Promise(
                (resolve, reject) => {
                    console.log("promise5_1 starts");
                    setTimeout(
                        () => {
                            resolve("this is promise5_1 resolve");
                        },
                        2000
                    );
                }
            );
            resolve(promise4_1);
        }
    ).then(
        (msg) => {
            console.log(msg);
            var promise5_2 =  new Promise(
                (resolve, reject) => {
                    console.log("promise5_2 starts");
                    setTimeout(
                        () => {
                            resolve("this is promise5_2 resolve");
                        },
                        2000
                    );
                }
            );
            return promise5_2;
        }
    ).then(
        (msg) => {
            console.log(msg);
            throw new Error();
        }
    ).catch(
        () => {
            console.log("exception catched after promise5_2 resolved");
        }
    );
    这个例子变得再复杂一些,除了在promise5中节外生枝promise5_1异步处理2秒,在2秒后回到主干后的.then()环节,我通过return返回一个Promise对象再次节外生枝promise5_2异步执行2秒,之后再次回到主干的.then()打印出消息并且抛出了异常,最终由catch捕获。


    // 并行+链式promise
    var promise6 = new Promise(
        (resolve, reject) => {
            var promiseArr = [];
            for (var i = 0; i < 5; ++i) {
                promiseArr.push(new Promise(
                    (resolve, reject) => {
                        console.log(`promise6_${i} starts`);
                        ((index) => { // 闭包处理i
                            setTimeout(
                                () => {
                                    console.log(`before promise6_${index} resolved`);
                                    resolve(`this is promise6_${index} resolve`);
                                },
                                index * 1000
                            );
                        })(i);
                    }
                ));
            }
            resolve(Promise.all(promiseArr));
        }
    ).then(
        (msgArr) => {
            console.log(`promise6 all resolved ${msgArr}`);
        }
    );

    这个例子主要是体验Promise.all(),这个函数其实创建返回了一个Promise对象,内部管理与并发了多个Promise流程(节外生枝了N个树叉),它等待它们全部完成或者任意失败之后会终结自己,在外层通过resolve将Promise.all()返回的集合式Promise对象串联(托管)起来,最终进入下一个then从而可以访问N个树叉的结果集合。
  • 相关阅读:
    Linux 配置 nginx + php
    Laravel 网站项目目录结构规划
    配置服务器 Ubuntu 记录+踩坑
    JavaScript 单例,Hash,抛异常
    易理解版八皇后
    获取bing每日图片
    OpenGL 学习笔记 01 环境配置
    [瞎JB写] C++多态
    c++ initialize_list
    最长上升子序列的二分优化
  • 原文地址:https://www.cnblogs.com/burtyang/p/9040275.html
Copyright © 2011-2022 走看看