Javascript中的Promise函数浅析

上一篇讲了生成器函数,本篇简单的分析一下Promise对象。
Promise 是一个 ECMAScript 6 提供的类对象,目的是更加优雅地书写复杂的异步任务,传统的方法是执行层层回调函数,缩进和结构混乱。

1.Promises的基本用法:

Promise通过构造函数来声明, 此构造函数只有一个参数,是一个函数,这个函数在构造之后会直接被异步运行,所以我们称之为起始函数。起始函数包含两个参数 resolve(解决) 和 reject(拒绝),而这两个参数也是函数,其结果返回到then方法的两个函数的参数中,调用方式如下:

 let p=new Promise(function(resolve,reject){
    setTimeout(()=>{
        if(Math.random()>0.5){
            resolve("好好学习天天向上");//承诺成功
        }else{
            reject("休息会");//承诺失败
        }
    },3000)
});
//p代表的是promise实例
p.then(function(data){//成功的回调函数
    console.log(data);
},function(err){//失败的回调函数
    console.log(err);
})

上面代码,resolve方法的结果传递给then第一个函数参数data,reject方法的结果传递给then第二个函数参数err。
另外Promise类,resolve和reject方法谁先执行了,Promise的状态就是谁的状态,后面的方法对于Promise的状态没有影响,resolve先执行,那么就传递给then回调函数bin执行,如果reject先执行,那么就传递给catch回调函数并执行.

2.Promises的.catch() 和 .finally()方法

Promise 类有 .then() .catch() 和 .finally() 三个方法,这三个方法的参数都是一个函数,.then() 可以将参数中的函数添加到当前 Promise 的正常执行序列,.catch() 则是设定 Promise 的异常处理序列,.finally() 是在 Promise 执行的最后一定会执行的序列,无论是否异常最后都会执行。 .then() 传入的函数会按顺序依次执行,有任何异常都会直接跳到 catch 序列,如果采用采用.catch()方法,那么.then()方法只需要一个函数参数即可,上面的代码改成如下:

    let p=new Promise(function(resolve,reject){
        setTimeout(()=>{
            if(Math.random()>0.5){
                resolve("好好学习天天向上");//承诺成功
            }else{
                reject("休息会");//承诺失败
            }
        },3000)
    });
    //p代表的是promise实例
    p.then(function(data){//成功的回调函数
        console.log(data);
    }).catch(function (err){
        console.log(err);
    }).finally(function () {
        console.log("End");
    });

3.Promises的链式调用

resolve() 中可以放置一个参数用于向下一个 then 传递一个值,then 中的函数也可以返回一个值传递给 then。但是,如果 then 中返回的是一个 Promise 对象,那么下一个 then 将相当于对这个返回的 Promise 进行操作:

    let t= new Promise(function (resolve, reject) {
        console.log(1111);
        resolve(2222);
    });
    t.then(function (value) {
        console.log(value);
        if(Math.random()>0.5){
            throw "Overflow";
        }
        return 3333;
    }).then(function (value) {
        console.log(value);
        throw "An error";
    }).catch(function (err) {
        console.log(err);
    });

上述链式调用中,第一个then方法的return返回值作为第二个then方法的输入参数,链式调用中只要一个环节异常,那就中断跳过接下来的then调用而执行catch方法,有趣的是Promise对象链式执行then catch方法时是只需一个函数参数,如果这种一个参数独立调用时会报错。比如如果写成t.then()和t.catch()两个执行语句,当Promise返回的是reject函数的值时,就报错。
如果then方法返回的是 Promise对象,那么下一个 then 将相当于对这个返回的 Promise 进行操作,比如如下的操作:

    function print(delay, message) {
        return new Promise(function (resolve, reject) {
            setTimeout(function () {
                console.log(message);
                resolve();
            }, delay);
        });
    }
    
    print(1000, "First").then(function () {
        return print(4000, "Second");
    }).then(function () {
        print(3000, "Third");
    });

4.等待Promises多个调用

对于等待多个独立的异步任务,可以用Promise.all来简化代码,Promise.all方法用于传入多个 Promise 实例,这个方法将一个Promise数组作为参数,然后创建一个新的Promise对象,只有数组中的Promise全部被解决,这个返回的Promise就会被解决执行then的resolve方法,而一旦其中有一个Promise失败了,那么整个心Promise对象就会被拒绝,执行catch或者reject方法。比如:

    let p=new Promise(function(resolve,reject){
        setTimeout(function(){
            resolve(1);
        },10000)
    })
    let p1=new Promise(function(resolve,reject){
        setTimeout(function(){
            resolve(2);
        },5000)
    })
    let p2=new Promise(function(resolve,reject){
        setTimeout(function(){
            resolve(3);
        },2000)
    })
    Promise.all([p,p1,p2]).then(function(value){
        console.log(value);//[1,2,3]
    },function(reason){
        console.log(reason);
    });

此任务组3个任务并行执行,所以等待时间按照最大的p计算为10秒,任务组的返回值是3个任务返回值组成的数组,3个任务有一个错误就执行 console.log(reason),只有3个都正确解决了,才会执行console.log(value)。

5.Promise.race()多个调用竞争

Promise.race方法同样是将多个 Promise 实例,包装成一个新的 Promise 实例。Promise.race方法的参数与Promise.all方法一样,但是执行的时候是那个任务先完成,返回那个任务的resolve和reject结果,示例代码如下:

    var p1 = new Promise(function(resolve, reject) {
        setTimeout(function () {
            console.log(1);
            resolve('one');
        }, 2000);
    });
    var p2 = new Promise(function(resolve, reject) {
        setTimeout(function () {
            console.log(2);
            resolve('two');
        }, 1000);
    });
    Promise.race([p1, p2]).then(function(value) {
        console.log(value); // "two"
        // 两个都完成,但 p2 更快
    });

执行结果为:
2
two
1

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值