Promise

作者: 江疏影子 | 来源:发表于2019-02-20 15:07 被阅读0次

    Promise是一个构造函数,自己有all resolve reject方法,原型上有.then .catch方法

    下面是一个例子

                var p=new Promise(function(resolve,reject){
                    setTimeout(function(){
                        console.log('执行完成');
                        resolve('成功了!!!!!');
                        //reject('失败了!!!!!')
                    },1000)
                });
    

    我们直接打开浏览器 可以看到在页面中会有输出 执行完成,但是我们并没有去调用这个函数,表明我们传入进去这个函数的时候就已经调用了,所以为了避免这个情况,我们就是将这个promise放在一个函数里面,需要的时候再调用。

            function testPromise(){
                var p=new Promise(function(resolve,reject){
                    setTimeout(function(){
                        console.log('执行完成');
                        resolve('成功了!!!!!');
                        //return 也可以代替resolve的作用,作为.then的回调函数的值
                        //reject('失败了!!!!!')
                    },1000)
                });
                return p;
            }
            testPromise();
    

    写到这里其实就有两个疑问了,为什么要包装这么一个函数?以及我们如何拿到resolvereject的值

    then与catch

    在之前说过原型上有.then.catch方法,.then是用来接收resolve的数据,.catch是用来接收reject数据的。

            testPromise().then(function(data){
                //这个data就是 上面函数 resolve的内容
                console.log(data)//成功了!!!!!
            })
    
            testPromise().catch(function(error){
                //这个data就是 上面函数 reject的内容
                console.log(error)//失败了!!!!!
            })
    

    以下是一个完整的例子

    function getNumber(){
        var p = new Promise(function(resolve, reject){
            //做一些异步操作
            setTimeout(function(){
                var num = Math.ceil(Math.random()*10); //生成1-10的随机数
                if(num<=5){
                    resolve(num);
                }else{
                    reject('数字太大了');
                }
            }, 0);
        });
        return p;
    }
    getNumber().then(function(data) {
        console.log('resolved');
        console.log(data);//输出的就是 resolve==> num的值
    }).catch(function(error){
        console.log(error)//输出的是 reject =>> “数字太大了”
    })
    

    如果随机生成的数字大于5就会被catch到,并且输出reject的结果。
    但是如果在.then的回调里面抛出了一个异常,并不是卡死整个js 而是进入.catch回调中来,这也是.catch的另外一个作用

    getNumber().then(function(data) {
        console.log('resolved');
        console.log(data);
        console.log(somedata); //此处的somedata未定义
    }).catch(function(error){
        console.log('reject');
        console.log(error)
    })
    

    在控制台中会显示


    Promise.all的使用

    首先我们来写一个链式操作

    function runAsync1(){
        var p = new Promise(function(resolve, reject){
            //做一些异步操作
            setTimeout(function(){
                console.log('异步任务1执行完成');
                resolve('随便什么数据1');
            }, 2000);
        });
        return p;
    }
    function runAsync2(){
        var p = new Promise(function(resolve, reject){
            //做一些异步操作
            setTimeout(function(){
                console.log('异步任务2执行完成');
                resolve('随便什么数据2');
            }, 2000);
        });
        return p;
    }
    function runAsync3(){
        var p = new Promise(function(resolve, reject){
            //做一些异步操作
            setTimeout(function(){
                console.log('异步任务3执行完成');
                resolve('随便什么数据3');
            }, 2000);
        });
        return p;
    }
    runAsync1().then(function(data){
          console.log(data);
          return runAsync2();
    }).then(function(data){
          console.log(data);
          return runAsync3();
    }).then(function(data){
          console.log(data);
    });
    

    那么在控制台中的打印结果就是


    每隔两秒就输出一个data

    如果采用all的方法,会发生什么事情呢?

    Promise.all([runAsync1(),runAsync2(),runAsync3()]).then(function(results){
        console.log(results)
    })
    

    所以在控制台中打印的结果就是

    隔两秒之后全部输出
    值得注意的一点就是,返回的results是一个数组。并且将这三个延时器并排进行了(不需要像上面等待六秒看到全部的结果)

    Promise.race的使用

    我们在使用Promise.all方法的时候,我们会收到每个setTimeout打印的值以及resolve的值,叫做「谁跑的慢,以谁为准执行回调」,那么Promise.race的作用就是「谁跑的快,以谁为准执行回调」。

    Promise.race([runAsync1(),runAsync2(),runAsync3()]).then(function(results){
        console.log(results)
    })
    

    并且我们将runAsync里面的setTimeout的时间一次修改为了 1000 2000 3000


    可以看到除了runAsync1resolve输出,其他的都没有输出,但是函数还是执行了。

    原文:https://www.cnblogs.com/whybxy/p/7645578.html

    相关文章

      网友评论

          本文标题:Promise

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