理解与使用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个树叉的结果集合。

 

posted on 2018-05-15 11:55  楚南  阅读(1313)  评论(0编辑  收藏  举报