ES6--异步操作之promise(续)

1. promise的出现

promise 是 commonJS下的一个规范 , 规范的就是JS中的异步操作方式

thenjs whenjs deferred(jq) , 基于promise开发出的实际代码

es 6 - > ecmaScript 6中已经加入原生JS实现了promise*

首先看一个小栗子

setTimeout(function(){
    alert(1);
},1000);
alert(2);

上面呢先出现2,后出现1;因为计时器是异步的,不影响后续执行。假如我们希望按照顺序去操作的话,promise就可以帮助我们实现。
当然我们首先看看用一般的方法怎么实现让它按照顺序执行,下面使用回调方式操作。

function show(time,fn){
    setTimeout(function(){
        console.log(time+'秒后:');
        fn();
    },time*1000);
}
show(1,function(){
    console.log('操作1');
});

试想,如果我们希望一秒后执行操作1,二秒后执行操作2,三秒后执行操作3,我们可以用下面的代码去写。

function show(time,fn){
    setTimeout(function(){  
        console.log(time+'秒后:');
        fn();   
    },time*1000);
}

show(1,function(){
    console.log('操作1');
    show(2,function(){
        console.log('操作2');
        show(3,function(){
            console.log('操作3');
        });
    });
});

但是呢,我们分析上面的代码,不好维护,所以呢,就出现了promise。下来我们正式介绍promise。

2. promise的介绍

  1. 状态 pending(等待) -> resolve(成功) reject(拒绝)
    状态一旦改变就不能再继续变化
  2. then方法 : 调用 resolve reject 状态所对应的回调函数

现在尝试使用promise改写以上代码

function show(time){
    var promise = new Promise(function(resolve,reject){     
        setTimeout(function(){  
            console.log(time+'秒后:');
            resolve();  //① 
        },time*1000);   
    });
    return promise;
}
show(1).then(function(){
    console.log('操作1');
},function(){
    console.log('失败');
});

上面代码会在一秒后打印操作1,如果将①换成reject( ),则会在一秒后打印失败。

现在使用promise解决上面层层嵌套的问题

show(1).then(function(){
            console.log('操作1');
            return show(2);
        })
        .then(function(){
            console.log('操作2');
            return show(3);
        })
        .then(function(){
            console.log('操作3');
        });

3. promise应用场景

首先看一个栗子,异步操作ajax。以下是一个典型的promise应用场景,结构非常清晰明了。

var getJSON = function(url) {
  var promise = new Promise(function(resolve, reject){
    var client = new XMLHttpRequest();
    client.open("GET", url);
    client.onreadystatechange = handler;
    client.responseType = "json";
    client.setRequestHeader("Accept", "application/json");
    client.send();

    function handler() {
      if (this.status === 200) {
        resolve(this.response);
      } else {
        reject(new Error(this.statusText));
      }
    };
  });

  return promise;
};

getJSON("/posts.json").then(function(json) {
  console.log('Contents: ' + json);
}, function(error) {
  console.error('出错了', error);
});

3. promise的辅助方法

首先把上面的代码拿下来

function show(time){
    var promise = new Promise(function(resolve,reject){ 
        setTimeout(function(){  
            console.log(time+'秒后:');
            reject();           
        },time*1000);       
    }); 
    return promise;
}

show(1).then(function(){
    console.log('成功');
}).catch(function(){
    console.log('失败');
});

Promise.all
看下面的例子

function p1(){
    var promise = new Promise(function(resolve,reject){
        setTimeout(function(){
            console.log('1秒后:');
            resolve();

        },1000);

    });
    return promise;
}
function p2(){
    var promise = new Promise(function(resolve,reject){
        setTimeout(function(){
            console.log('2秒后:');
            reject();

        },2000);

    });
    return promise;
}
function p3(){
    var promise = new Promise(function(resolve,reject){
        setTimeout(function(){
            console.log('3秒后:');
            resolve();

        },3000);

    });
    return promise;
}
//要想等上面三个都是成功的时候触发,可以这样做
var p = Promise.all([p1(),p2(),p3()]);

p.then(function(){
    console.log('都成功的状态才会触发');
},function(){
    console.log('只要有一个失败的就会走');
});

Promise.race

p.then(function(){
    console.log('只要有一个成功的状态就会触发');
},function(){
    console.log('只要有一个失败的就会走');
})

4. 和JQ结合使用

在Jq中promise使用Deferred()来实现的,举例如下

function show(time){    
        var dfd = $.Deferred();        
        setTimeout(function(){      
            console.log(time+'秒后:');
            dfd.reject();           
        },time*1000);       
        return dfd; 
}

show(1).then(function(){
    console.log('成功');
},function(){
    console.log('失败');
});

done和fail

show(1).done(function(){
    console.log('成功');
}).fail(function(){
    console.log('失败');
});

when类似于promise.all

function show1(){
        var dfd = $.Deferred();    
        setTimeout(function(){
            console.log('第一个');
            dfd.resolve();          
        },2000);        
        return dfd; 
}

function show2(){   
        var dfd = $.Deferred();        
        setTimeout(function(){
            console.log('第二个');
            dfd.resolve();          
        },5000);        
        return dfd; 
}

$.when(show1(),show2()).then(function(){
    console.log('都成功才触发');
});
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值