关于javascript的单线程和异步解决方案Promise的思考

             大家都知道js是单线程的,所谓单线程就是两段js代码是不可能同时执行的,js有能力修改Dom,同一时间内不可能同时执行两段代码,两句都不行,这是为了避免DOM渲染的冲突。于是出现了SetTimeout,Ajax这些异步的函数,函数同步执行时遇到异步函数,异步函数被放到异步队列,代码自上往下执行,会根据事件轮询机制执行异步函数。

             在工作中遇到这么一个问题,例如我要根据返回的数据动态生成一些元素,再对这些元素进行实例化,如果不使用回调函数的话这是会报错的,undefined,下图是用回调函数解决

        

思考一个问题,如果success里面的回调函数有多个,那么传参的时候要传入多个回调函数,再看一下下面的例子

传入多个回调函数控制台依次打印123,456,789,那么问题来了,我们是否可以用Promise改写一下呢?Promise就是为了解决异步而存在的

或者是

上面这里输出:

我们要做的就是在函数体里面new一个Promise对象,对象传入一个函数,再对这个函数传resolve,reject这两个方法,分别代表成功的方法和失败的方法,resolve,reject这两个方法再传参数,这样的话,后面在then的回调方法可以拿到,看下图

我觉得吧,promise其实是把原来传参的回调函数方式,抽出来写成了链式操作的形式,而then的第一个和第二个方法分别代表成功和失败的回调,这样代码易理解易维护。我们再举一些其他的例子,假如存在3个异步的请求,看下面

function runAsync(){
                var p=new Promise(function(resolve,reject){
                     $.ajax({
                         type:"get",
                         url:"pdlist1.json",
                         async:true,
                         dataType:"json",
                         success:function(data){
                             resolve("我成功了1");
                         },
                         error:function(data){
                             reject("我出错了1")
                         }
                     });
                })
                return p
            }
            function runAsync1(){
                var p=new Promise(function(resolve,reject){
                     $.ajax({
                         type:"get",
                         url:"pdlist1.json",
                         async:true,
                         dataType:"json",
                         success:function(data){
                             resolve("我成功了2");
                         },
                         error:function(data){
                             reject("我出错了2")
                         }
                     });
                })
                return p
            }
            function runAsync2(){
                var p=new Promise(function(resolve,reject){
                     $.ajax({
                         type:"get",
                         url:"pdlist1.json",
                         async:true,
                         dataType:"json",
                         success:function(data){
                             resolve("我成功了3");
                         },
                         error:function(data){
                             reject("我出错了3")
                         }
                     });
                })
                return p
            }

使用promise异步调用

runAsync().then(function(data){
                console.log(data);
                return runAsync1();
            },function(data){
                console.log(data);
                return runAsync1();
            }).then(function(data){
                console.log(data);
                 return runAsync2();
            },function(data){
                console.log(data);
                 return runAsync2();
            }).then(function(data){
                console.log(data);
            },function(data){
                console.log(data);
            })

如果3个异步方法都成功,会依次输出:我成功了1,我成功了2,我成功了3,我上面标明的红色返回一个方法,这个方法可以指明成功或者失败时做哪个的回调,再做个假设如果runAsync失败,会依次输出:我出错了1,我成功了2,我成功了3

关于catch的用法,catch用于捕获异常

假设上面的代码runAsync失败,其他成功,代码简写成这样

runAsync().then(function(data){
                console.log(data);
                return runAsync1();
            }).then(function(data){
                console.log(data);
                return runAsync2();
            }).then(function(data){
                console.log(data);
            }).catch(function(data){
                console.log(data);
            })            

控制台输出:我出错了1,代码也不会往下执行了

假设上面的代码runAsync1失败,其他成功,则会输出:我成功了1,我出错了2,可以自己写代码慢慢体会

 

最后是两个关于Promise.allPromise.race的用法

Promise.all是几个异步函数并行执行都完成时触发回调方法,有一个出错或者没完成都不会执行回调方法,以上面的3个异步Ajax请求为例:

Promise.all([runAsync(),runAsync1(),runAsync2()]).then(function(data){
                console.log(data);   // 3个成功输出数组【我成功了1","我成功了2","我成功了3"】
                console.log("完成")  //3个成功输出完成
            }).catch(function(data){
                console.log(data)  //无输出
            })

Promise.race是哪个异步函数最先完成为准就执行方法,race意为赛跑,以最快的为准

Promise.race([runAsync(),runAsync1(),runAsync2()]).then(function(data){
                console.log(data); //输出我成功了1,runAsync()最先完成
                console.log("完成")
            }).catch(function(data){
                console.log(data)
            })

以上为学习Promise的总结

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值