ES6之Promise

什么是promise?

总所周知,JS是单线程的。但是我们又要让它实现多线程的效果,最大众的方法就是用异步。而promise就是更简洁方便的异步编程方案。

    // 平常我们所使用的异步,如AJAX
...
    xmlhttp.onreadystatechange=function()
    {
        if (xmlhttp.readyState==4 && xmlhttp.status==200)
        {
            document.getElementById("myDiv").innerHTML=xmlhttp.responseText;
        }
    }
...

使用promise后

const ajax = function(url) {
  const promise = new Promise(function(resolve, reject){
    const handler = function() {
      if (this.readyState == 4 && this.status === 200) {
        resolve(this.response);
      } else {
        reject(new Error(this.statusText));
      }
    };
    const client = new XMLHttpRequest();
    client.open("GET", url);
    client.onreadystatechange = handler;
    client.responseType = "json";
    client.setRequestHeader("Accept", "application/json");
    client.send();

  });

  return promise;
};

// 下面是精华
ajax("/posts.json").then(function(json) {
  console.log('Contents: ' + json);
}, function(error) {
  console.error('出错了', error);
});

这样就比原生的js方法简洁明了很多,并且有利于复用。这种链式写法的好处在于,先统一执行AJAX逻辑,不关心如何处理结果,然后,根据结果是成功还是失败,在将来的某个时候调用success函数或fail函数。


promise的用法

首先,promise是一个对象,我们使用它时,必须要new一个Promise实例。

 var p = new Promise(function);//这里传入的参数是需要执行的函数

其次,promise使用方法

var p = new Promise(function(resolve,reject){
    if(xxxx){
        resolve("yes");
    }else{
        reject("no");
    }
});

p.then(function(successState){
    console.log(successState);
}).catch(function(failState){
    console.log(failState);
})

这里可以显然易见,
1. 创建promise实例,实例传入要执行的函数。函数可以传入两个参数(函数):一个是函数执行成功后需要回调的函数,一个是失败后需要回调的函数。
2. 创建完毕后,使用then来传入resolve,使用catch来传入reject。

promise的好处显然可见: 是在异步执行的流程中,把执行代码和处理结果的代码清晰地分离了,也方便复用。


promise使用方法扩展

promise之resolve(promise)

有一点需要注意的是,resolve函数返回的是promise对象。即使不是promise对象的参数传入resolve函数,返回的依然是promise对象。

var original = Promise.resolve('我在第二行');
var cast = Promise.resolve(original);
cast.then(function(value) {
  console.log('value: ' + value);
});
console.log('original === cast ? ' + (original === cast));

/*
*  打印顺序如下,这里有一个同步异步先后执行的区别
*  original === cast ? true
*  value: 我在第二行
*/
promise串用
var a = 1;
var p = new Promise((resolve,reject)=>{
    if(a === 1){
        resolve("yes1");
    }else{
        reject("no1");
    }
});
var p2 = new Promise((resolve,reject)=>{
    if(a === 1){
        resolve("yes2");
    }else{
        reject("no2");
    }
});
p.then((state1)=>{
    console.log(state1);  // yes1
    return p2; 
    //这里返回一个设置好的promise是为了下面的then传参。
    //如果没有这个p2,虽然下面的then也可以用,但是state2参数为underfined
}).then((state2)=>{
    console.log(state2);  // yes2
}).catch((failState)=>{
    console.log(failState);
});

这里有必要说一下,promise的catch方法是冒泡传递的,所以把它放在最后没毛病。只要中间过程中有个reject了,后面的将不会再执行,并且返回reject();如,

var a = 1;
var p = new Promise((resolve,reject)=>{
    if(a === 1){
        resolve("yes1");
    }else{
        reject("no1");
    }
});
var p2 = new Promise((resolve,reject)=>{
    if(a === 2){            //这里判断条件改为2
        resolve("yes2");
    }else{
        reject("no2");
    }
});
var p3 = ....  //与上面 p1,p2一样

p.then((state1)=>{
    console.log(state1);  // yes1
    return p2;      // 返回reject(),故下面then不执行
}).then((state2)=>{
    console.log(state2);  
    return p3; 
}).then((state3)=>{
    console.log(state3);  
}).catch((failState)=>{
    console.log(failState); // no2,捕抓到p2冒泡的reject
});
promise的并用
Promise.all()方法

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

// 延用上面p1,p2,p3的例子
Promise
    .all([p1, p2, p3])   //这里传入的参数必须是以数组的形式
    .then((results)=>{
        console.log(results); //返回的是一个数组
    }).catch((fail)=>{
        console.log(fail);  //返回的是失败的promise的reject()
    });

只有当p1,p2,p3都成功执行完了,返回的都是resolve()后,才会进行到then();若是p1,p2,p3中有一个返回的是reject(),那么会直接进入catch();
这里写图片描述

Promise.race()方法

该方法就像他的名字一样,”race”竞速;仍然以p1,p2,p3为例子

Promise
    .race([p1, p2, p3])
    .then(function(results){
        console.log(results);  // yes1
    }).catch((fail)=>{
            console.log(fail);  //返回的是失败的promise的reject()
        });

p1,p2,p3当中只要有一个执行完成了,进入resolve()回调,就立马进入then()方法。剩下的两个不再执行。也就是“谁快就运行谁的回调”(race竞速)。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值