Promise链式调用方案

作者: stois | 来源:发表于2016-11-11 12:25 被阅读2424次

最近在用node查询mysql数据库,一个方法里需要做最多5次的纵深查询。
第一个版本写了5层回调,丑陋不堪:

   this.insertUser  = function(openId, floorName , func ){
        var feedback = 'o' ;
        var connection = mysql.createConnection(this.DBconfig);
            connection.query('INSERT INTO Floor SET ?', {Builder_open_id: openId , Floor_name: floorName }, function(err, result) {
            if(err){
                //...
            }
            else{
                var floor_id = result.insertId ;
                connection.query('INSERT INTO Layer SET ?', { Floor_id: floor_id }, function(err1, result) {
                    if(err1){
                        //
                    }
                    else{
                        connection.query('...'. function(err, result){
                            //some other query below
                        })
                    }
                })
            } 
       });


    };

于是开始寻求解决方案(当时我还不知道generator这种神奇的东西),看到了promise,遂进行了修改:
将方法里的查询代码迁移出来,成为一个新方法,返回一个promise,如:

this.insertFloor = (connection , openId , floorName ) => {
        return new Promise( (resolve , reject ) => {
            connection.query('INSERT INTO Floor SET ?', {Builder_open_id: openId , Floor_name: floorName }, function(err, result) {
                if(err){
                    reject(err);
                }
                else{
                    resolve(result);
                }
             });
        } ) 
    };

然后根据promise的标准写法,以上方法执行完成后需要使用then方法:

this.insertFloor(connection, openId , floorName).then(res=>{
//...
}, err=>{
//...
})

写到这里我产生了疑问:如果要在then的成功回调里,继续写promise,那么和写五层回调的原代码又有什么区别?
最终看到alinode的文章才恍然大悟:then里的参数真是个神奇的东西。

var promise = new Promise(function(resolve, reject) {
    if (someCondition) {  // succeed
        resolve(1);
    } else {   // fails
        reject("err");
    }
});

promise.then(function(future) {
    console.log(future);  // log 1 if someCondition = true
    return 2;
}, function(err) {
    console.log(err);  // log err if someCondition = false
}).then(function(future) {
    console.log(future);  // log 2 if someCondition = true
});

看到这里你发现return的值是可以传给下一个then的!于是按照文中所说,链式调用then的模型如下:

userdb.query(userid)
.then(function(user) {
  return postdb.query(user.latestPost.id);
}).then(function(post) {
  return replydb.query(post.latestReply.id);
}).then(function(reply) {
  // use reply to do something...
}).catch(function(reason) {
   // error handling
});

这个模型比较简单,结合实际的问题,仍然需要考虑的是:
如果在then里写了一个条件判断,返回不同的值,如:

then(res=>{
      if(a)
          return 1;
      else    
          return 0;
}).then(res=>{
          if(res == 1) 
                //....
          else
                //....
})

显然没有问题,因为hold住了所有的返回。那么如果把return 0 这一句去掉呢?后面会收到怎样的返回值?还是会被直接忽略?

经过测试后,如果有一个条件没有return,在下一个then里将收到undefined。这告诉我们,不要偷懒。

在完成代码改造后,可以使用co来进行润色,使其更加“同步化”。

相关文章

  • Promise链式调用方案

    最近在用node查询mysql数据库,一个方法里需要做最多5次的纵深查询。第一个版本写了5层回调,丑陋不堪: 于是...

  • js promise图解

    链式调用 封闭promise

  • 嵌套的promise执行顺序

    外部promise有多个then链式调用,第一个then里面执行另一个promise,也带多个then链式调用,他...

  • Promise链式调用

    做了一个博客项目,有一个过程如下: 封装request函数(用axios发送请求),axios会返回一个promi...

  • Promise链式调用

    一、Promise对象 承诺一定会实现,更简单的处理异步请求。同时更加方便使用链式调用。缺点:Promise对象状...

  • Promise 链式调用

    Promise status状态,有三种状态pendding、resolved、rejected,状态由 pend...

  • ES6

    AJAX 异步网络请求 Promise 使用了Promise对象之后可以链式调用的方式组织代码 Promise.a...

  • 手写Promise

    1. 简易版Promise,只能调用一次then,不能链式调用:

  • Promise用法详解

    参考promise|深入理解 promise:promise的三种状态与链式调用 Promise对象只有三种状态 ...

  • async和await

    promise链 原来用promise的链式调用方式,then 中原本就返回了一个promise async 函数...

网友评论

    本文标题:Promise链式调用方案

    本文链接:https://www.haomeiwen.com/subject/ftkfpttx.html