关于把传统的callback回调改写成es6中promise风格

NodeJs是目前比较火的开发语言之一,现在很多公司都在开始使用NodeJs语言进行项目开发。大家都知道node最好的就行回调,但是最不好的也是回调。如果一个功能比较复杂的话就可能会会出现callback hells(回调大坑)。所以在新的node版本里面都支持es6的promise,以前要使用promise的时候,需要使用Q函数库或者bulebird(蓝鸟)函数库,后面node把promise接入了node基础版本库里面,如果需要使用promise就不需要引用这俩个函数库。如果就性能上来说的话,bulebird的执行速度会比es6的promise要快。所以在使用的时候可以看情况来选择对自己项目有利的方式。好了废话不多说了,下面就关于传统的callback写法和promise写法以及把传统的cb转换成promise,这里不使用官方的promisify,因为官方的promisify方式只能适合nodeCallback风格(1.回调函数是作为参数的最后一个;2.回调函数接收俩个参数err,data),所有改写了一下,满足不一定是nodeCallback风格的回调都能转换成promise。

1.传统的callback回调方式

let callFn = (arg1,arg2,cb)=>{//如果arg1>arg2回调正常,否则回调错误信息
    setTimeout(function(){
        if(arg1>arg2){
            cb(null,arg1+arg2);
        }else{
            cb(new Error('err'),null);
        }
    },5000);
}

//调用
callFn(1,2,function(err,data){
    if(err){
        //错误处理
    }else{
        //正确处理
    }
});

2.使用es6来写上面的功能

let promiseFn = (arg1,arg2)=>{
    return new Promise((resole,reject)=>{
        if(arg1>arg2){
            resole(arg1+arg2);
        }else{
            reject(new Error('err'));
        }
    }); 
};

//调用
promiseFn(1,2).then(data=>{
    //正确处理
}).catch(err=>{
    //错误处理
});

通过上面俩个的对比明显promise方式更加直观,而且还不容易出现callback hells。
3.把传统的callback改写为promise
下面是转换方式

/**
* @param fn: callback回调函数
* @param _pointNum: 回调函数所在参数的位置
*/
let _promisify = (fn,_pointNum)=>{
    return function(){
        let args = [];
        if(_pointNum){
            return new Promise((resole,reject)=>{
                for(var i=0,key=0;i<=arguments.length;i++){
                    if(i==(_pointNum-1)){
                        args[i] = function(err,res){
                            return err?reject(err):resole(res);
                        }
                    }else{
                        args[i] = arguments[key];
                        key++;
                    }
                }
                fn.apply(this,args);
            });
        }else{
            for(var i=0;i<arguments.length;i++){
                args[i] = arguments[i];
            }
            return new Promise((resole,reject)=>{
                fn.apply(this,[].concat(args,function(err,res){
                    return err?reject(err):resole(res);
                }))
            });
        }

    }
 };
 /*下面是把上面的callback函数转换为promise函数,而且这里
 的传统调法师callFn(1,2,function(){}),cb回调是最后一个
 参数,所以改写成promise的时候不用传_pointNum参数*/

 _promisify(callFn)(1,2)
 .then(resp=>{
     //成功处理
 }
).catch(err=>{
    //错误处理
});

/如果把callFn函数改写为下面
let callFn = (arg1,function(){},arg2)=>{}//这种形式
那么上面改为promise函数的时候为
_promisify(callFn,2)(1,2).then().catch()

如果真的想把不是nodeCallback风格的代码转换成promise格式的话,上面是把cb回调函数不是最后一个参数的形式实现,如果想要彻底实现的话,可以再加一个参数在_promisify(fn,_pointNum,_checkSuccess),其中_checkSuccess是判断返回的是成功还是失败来决定是resole(),还是reject()。这种方式就让看客们自己去实现。欢迎大家把实现方式留言在下方的评论里面,大家参考一下,,谢谢。。。。。。。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值