Promise

2019-02-20  本文已影响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

上一篇 下一篇

猜你喜欢

热点阅读