ECMAScript 6 入门笔记(五)异步promise,Generator,async

ECMAScript 6 入门原文 – 阮一峰
ECMAScript 6 入门笔记(一)let,const,解构
ECMAScript 6 入门笔记(二)String,RegExp
ECMAScript 6 入门笔记(三)数值,Array
ECMAScript 6 入门笔记(四)函数,对象

ECMAScript 6 入门笔记(五)异步promise,Generator,async
ECMAScript 6 入门笔记(六)Class
ECMAScript 6 入门笔记(七)Symbol,set和map
ECMAScript 6 入门笔记(八)Proxy,Reflect

前面弄完了ECMAScript6的基础对象扩展,下来来看下异步编程的三个方法

Promise

Promise.prototype.then()
Promise.prototype.catch()
Promise.all()
Promise.race()
Promise.resolve()
Promise.reject()
两个有用的附加方法

所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。Promise 提供统一的 API,各种异步操作都可以用同样的方法进行处理。

(1)对象的状态不受外界影响。Promise对象代表一个异步操作,有三种状态:Pending(进行中)、Resolved(已完成,又称 Fulfilled)和Rejected(已失败)。
(2)一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise对象的状态改变,只有两种可能:从Pending变为Resolved和从Pending变为Rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果。

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

Promise也有一些缺点。首先,无法取消Promise,一旦新建它就会立即执行,无法中途取消。其次,如果不设置回调函数,Promise内部抛出的错误,不会反应到外部。第三,当处于Pending状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。

var promise = new Promise(function(resolve, reject) {
  // ... some code
     if (/* 异步操作成功 */){
       resolve(value);
     } else {
       reject(error);
     }
});

Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolve和reject。它们是两个函数,由JavaScript引擎提供,不用自己部署。

resolve函数的作用是,将Promise对象的状态从“未完成”变为“成功”(即从Pending变为Resolved),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;reject函数的作用是,将Promise对象的状态从“未完成”变为“失败”(即从Pending变为Rejected),在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。

promise.then(function(value) {
   
  // success
}, function(error) {
   
  // failure
});

下面是一个用Promise对象实现的Ajax操作的例子

var getJSON = function(url){
        var promise = new Promise((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.readyState !== 4){
                return;
            }   
            if(this.status === 200){
                console.log(this.response);
                resolve(this.response.toString());
            }else{
                reject(new Error(this.statusText));
            }
        };
    });
    return promise;
};

getJSON("/posts.json").then((json) => {
    document.write("Content:"+json);
},function(error){
    console.log('出错了',error);
});

posts.json
"{
   a:1,b:2,c:3}"

Promise.prototype.then
Promise实例具有then方法,也就是说,then方法是定义在原型对象Promise.prototype上的。它的作用是为Promise实例添加状态改变时的回调函数。前面说过,then方法的第一个参数是Resolved状态的回调函数,第二个参数(可选)是Rejected状态的回调函数。
then方法返回的是一个新的Promise实例(注意,不是原来那个Promise实例)。因此可以采用链式写法,即then方法后面再调用另一个then方法。

采用链式的then,可以指定一组按照次序调用的回调函数。这时,前一个回调函数,有可能返回的还是一个Promise对象(即有异步操作),这时后一个回调函数,就会等待该Promise对象的状态发生变化,才会被调用。

getJSON("/post/1.json").then(function(post) {
   
  return getJSON(post.commentURL);
}).then(
    //resovle状态handler
    function funcA(comments) {
   
        console.log("Resolved: ", comments);
     },
    //reject状态handler
    function funcB(err){
   
        console.log("Rejected: ", err);
    }
);

//最好不用then里面设置两个function,设置在catch里
getJSON("/post/1.json").then(function(data) { //cb
    // success
}).catch(function(err) {
   
    // error
});

Promise.prototype.catch
Promise.prototype.catch方法是.then(null, rejection)的别名,用于指定发生错误时的回调函数。

getJSON('/posts.json').then(function(posts) {
  // ...
}).catch(function(error) {
  // 处理 getJSON 和 前一个回调函数运行时发生的错误
  console.log('发生错误!', error);
});

p.then((val) => console.log('fulfilled:', val))
  .catch((err) => console.log('rejected', err));

上面代码中,getJSON方法返回一个 Promise 对象,如果该对象状态变为Resolved,则会调用then方法指定的回调函数;如果操作抛出错误,状态就会变为Rejected,就会调用catch方法指定的回调函数。

//catch冒泡
getJSON('/post/1.json').then(function(post) {
   
  return getJSON(post.commentURL);
}).then(function(comments) {
   
  // some code
}).catch(function(error) {
   
  // 处理前面三个Promise产生的错误
});

catch方法返回的还是一个 Promise 对象,因此后面还可以接着调用then方法。

var someAsyncThing = function() {
   
  return new
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值