封装Promise

298 阅读2分钟
  function timeOut(ms){        
    return new Promise((resolved, rejected)=>{           
     setTimeout(()=>{               
     resolved('res.data')         
       })    
    })   
 }    
timeOut(2000).then((val)=>{      
  console.log(val);   
 })

Promise封装Ajax

 const getJSON = function (url) {        
        return new Promise((resolve, reject) => {            
        const xhr = new XMLHttpRequest();            
        xhr.open('GET', url);            
        xhr.onreadystatechange = handler;            
        xhr.responseType = 'json';            
        xhr.setRequestHeader('Accept', 'application/json');            
        xhr.send();            
        function handler() {                
        //this.readyState有三个状态,2代表开始、3代表过程中、4代表结束                 
        console.log(this.readyState);                
        if (this.readyState !== 4) {                    
            return;                
        }                
        if (this.status === 200) {                    
            resolve(this.response);               
         } else {                   
             reject(new Error(this.statusText));                
                }
         }        
    })    
}    
        getJSON('https://free-api.heweather.net/s6/weather/now?
        location=beijing&key=4693ff5ea653469f8bb0c29638035976')        
        .then((res) => {           
             console.log(res);        
        }, 
        function (error) {          
          console.error(error);     
       })

     //then()方法     
    //then()第一个参数是relove的回调函数,第二个参数是可选的,是reject的回调函数    
    //then()返回一个新的Promise实例,可以采用链式调用

    //then方法的链式调用     
        getJSON('https://free-api.heweather.net/s6/weather/now?
        location=beijing&key=4693ff5ea653469f8bb0c29638035976')      
         .then((res) => {          
               return res.HeWeather6;         
        }).then((HeWeather6) => {        
               console.log(HeWeather6);     
    })

Promise对象的其他方法(resolve()、reject()、all()、race()、done()、finally())

1、resolve()能将现有的任何对象转换为Promise对象

    let p = Promise.resolve('foo');
    let p = new Promise(resolve=>resolve('foo'));
    p.then((data)=>{
    console.log(data);//foo
    })

2、reject()方法返回一个新的Promise实例,该实例的状态为rejected

let p2 = Promise.reject(new Error('出错了'));
//等价于 let p2 = new Promise((resolve,reject)=>reject(new Error('出错了)));
p2.catch(err => {
    console.log(err);
})

3、all()方法

all()方法提供了并行执行异步操作的能力,并且再所有异步操作执行完后才执行回调

试想一个页面聊天系统,我们需要从两个不同的URL分别获得用户的的个人信息和好友列表,这两个任务是可以并行执行的,用Promise.all实现如下

let meInfoPro = new Promise( (resolve, reject)=> {
    setTimeout(resolve, 500, 'P1');
});
let youInfoPro = new Promise( (resolve, reject)=> {
    setTimeout(resolve, 600, 'P2');
});
// 同时执行p1和p2,并在它们都完成后执行then:
Promise.all([meInfoPro, youInfoPro]).then( (results)=> {
    console.log(results); // 获得一个Array: ['P1', 'P2']
});

race()方法

有些时候,多个异步任务是为了容错。比如,同时向两个URL读取用户的个人信息,只需要获得先返回的结果即可。这种情况下,用Promise.race()实现:

let meInfoPro1 = new Promise( (resolve, reject)=> {
    setTimeout(resolve, 500, 'P1');
});
let meInfoPro2 = new Promise( (resolve, reject)=> {
    setTimeout(resolve, 600, 'P2');
});
Promise.race([meInfoPro1, meInfoPro2]).then((result)=> {
    console.log(result); // P1
});


Promise.all接受一个promise对象的数组,待全部完成之后,统一执行success;Promise.race接受一个包含多个promise对象的数组,只要有一个完成,就执行success