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

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

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

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

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

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

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

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

上面这里输出:关于javascript的单线程和异步解决方案Promise的思考

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

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

我觉得吧,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的总结

相关文章:

  • 2022-03-08
  • 2021-08-27
  • 2022-12-23
  • 2021-08-16
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-04-18
  • 2021-10-29
相关资源
相似解决方案