ES6中promise详解

Promise对象有以下两个特点:

(1)对象的状态不受外界影响。Promise对象代表一个异步操作,有三种状态:Pending(进行中)、Resolved(已完成,又称 Fulfilled)和Rejected(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。这也是Promise这个名字的由来,它的英语意思就是“承诺”,表示其他手段无法改变。

(2)一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise对象的状态改变,只有两种可能:从Pending变为Resolved和从Pending变为Rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果。就算改变已经发生了,你再对Promise对象添加回调函数,也会立即得到这个结果。这与事件(Event)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的。

有了Promise对象,就可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。此外,Promise对象提供统一的接口,使得控制异步操作更加容易。

简单来说,Promise 就是用同步的方式写异步的代码,用来解决回调问题。

/**
 * .then()链式结构写法
*/
function country(){
    return new Promise((res,rej)=>{
        setTimeout(() => {
            console.log('中国')
            res('中国 + 湖南')
        }, 1000);
    })
}
function province(data){
    return new Promise((res,rej)=>{
        setTimeout(() => {
            console.log(data + ' + 长沙')
            res(data + '+ 长沙')
        }, 1000);
    })
}
function city(data){
    return new Promise((res,rej)=>{
        setTimeout(() => {
            console.log(data + ' + 雨花区')
            res('end')
        }, 1000);
    })
}
country().then(res=>{return province(res)}).then(res=>{return city(res)})

/**
 * .catch()回调
 * 因为Promise的特性,多个promise对象链式调用时,有一个的状态变为reject了,后面的就不会再执行下去了
*/
function country(){
    return new Promise((res,rej)=>{
        setTimeout(() => {
            console.log('中国')
            res('中国 + 湖南')
        }, 1000);
    })
}
function province(data){
    return new Promise((res,rej)=>{
        setTimeout(() => {
            console.log(data + ' + 长沙')
            rej('省份方法报错')
        }, 1000);
    })
}
function city(data){
    return new Promise((res,rej)=>{
        setTimeout(() => {
            console.log(data + ' + 雨花区')
            res('end')
        }, 1000);
    })
}
country().then(res=>{return province(res)}).then(res=>{return city(res)}).catch(err=>{
    console.log(err)
})

 

 

/**
 * .all()方法回调
 * Promise 的 all 方法提供了并行执行异步操作的能力,并且在所有异步操作执行完后才执行回调。
*/
function country(){
    return new Promise((res,rej)=>{
        setTimeout(() => {
            console.log('中国')
            res('start')
        }, 1000);
    })
}
function province(data){
    return new Promise((res,rej)=>{
        setTimeout(() => {
            console.log('长沙')
            rej('省份方法报错')
        }, 1000);
    })
}
function city(data){
    return new Promise((res,rej)=>{
        setTimeout(() => {
            console.log('雨花区')
            res('end')
        }, 1000);
    })
}
Promise.all([country(),province(),city()]).then(function(results){
    console.log("都执行完毕");
    console.log(results);
});

与链式调用相比可以发现,所有的打印都执行,并没有一个异常抛出而中断。

/**
 * .race()方法
 * race 按字面解释,就是赛跑的意思。
 * race 的用法与 all 一样,只不过 all 是等所有异步操作都执行完毕后才执行 then 回调,而 race 的话只要有一个异步操作执行完毕,就立刻执行 then 回调。
 * 注意:其它没有执行完毕的异步操作仍然会继续执行,而不是停止。
*/
function requestImg(){
    var p = new Promise(function(resolve, reject){
        var img = new Image();
        img.onload = function(){
            resolve(img);
        }
        img.src = 'xxxxxx';
    });
    return p;
}

//延时函数,用于给请求计时
function timeout(){
    var p = new Promise(function(resolve, reject){
        setTimeout(function(){
            reject('图片请求超时');
        }, 5000);
    });
    return p;
}

Promise.race([requestImg(), timeout()]).then(function(results){
    console.log(results);
}).catch(function(reason){
    console.log(reason);
});
//上面代码 requestImg 函数异步请求一张图片,timeout 函数是一个延时 5 秒的异步操作。我们将它们一起放在 race 中赛跑。
//如果 5 秒内图片请求成功那么便进入 then 方法,执行正常的流程。
//如果 5 秒钟图片还未成功返回,那么则进入 catch,报“图片请求超时”的信息。

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值