深入解析ES6中的promise(2)

分析: 从这个例子中可以看出promise的异步,因为前面的两部分代码还没有执行,就已经输出了Hi。另外可以确定的是 Resolved 一定是在 Promise之后输出的,这个顺序是不可能有问题的。

下面的例子是一个异步添加图片的url的例子    

function loadImageAsync(url) { return new Promise(function(resolve, reject) { var image = new Image(); image.onload = function () { resolve(image); }; image.onerror = function() { reject(new Error('Could not load image at' + url)); } image.src = url; }); }

如果加载成功就使用resolve方法,如果失败就使用reject方法。

下面的例子是阮一峰老师封装的Ajax的例子,是在太好,没法不直接拿来参考~ 

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.readyState !== 4) { return; } 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); });

  这里应该大家都可以看懂,值得注意的是:handler这个处理函数的使用在这里显得很巧妙。

第三部分: Promise.prototype.then()

  在上一部分,我们实际上已经介绍了then()方法,而这里需要强调的有两点。

  第一: then()方法是Promise原型上定义的方法。

  第二:then()方法支持链式调用,上一个then()方法调用后返回的结果会传给下一个then方法中。

第一:我们再chrome中输入 Promise.prototype可以看到下面的例子:

深入解析ES6中的promise

可以看出在Promise的原型中确实是由then方法的。(注:比如我们想看Array这个内置对象有哪些方法,我们就可以直接在chrome中输入Array.prototype,然后就可以看到对应方法的列表了)

第二: then()的作用是为Promise实例添加状态改变时的回调函数。前面说过,then方法的第一个参数是Resolved状态的回调函数,第二个参数(可选)是Rejected状态的回调函数。

    then()由于支持链式调用,所以也可以写成下面这样:

getJSON("/posts.json").then(function(json) { return json.post; }).then(function(post) { // ... });

  第一个回调函数完成以后,会将返回结果作为参数,传入第二个回调函数。

看下面的这里例子:

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

  即第一个then又返回了一个promise,如何这个promise的状态变成了 Resolved,那么就会执行第二个then的第一个函数, 如果变成了 Rejected,就会执行第二个第二个函数。

第四部分: Promise.prototype.catch()

   Promise.prototype.catch()方法实际上是then(null, rejection)方法的别名, 这里使用catch()纯粹是为了便于使用和理解。

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

  在之前的例子中,我们讲解then()方法接受两个参数,第一个参数是pending变成resolved之后执行的函数,它是必选的; 第二个参数是pending变成rejected之后执行的函数,它是可选的。

  我们建议,最后不要使用第二个参数,取而代之我们最好使用catch(),如下所示:

// bad promise .then(function(data) { // success }, function(err) { // error }); // good promise .then(function(data) { //cb // success }) .catch(function(err) { // error });

  值得注意的是:catch()方法返回的还是一个Promise对象,我们可以在后面继续使用then进行链式调用。

第五部分:Promise.all()

  Promise.all()方法用于将多个Promise实例包装成一个新的Promise实例,如下所示:

var p = Promise.all([p1, p2, p3]);

  其中的p1,p2,p3都是Promise对象实例,如果不是,就会先调用下面讲到的Promise.resolve方法,将参数转为Promise实例,再进一步处理。

  p的状态由p1,p2,p3决定, 分成下面的两种情况:

•只有p1、p2、p3的状态都变成fulfilled,p的状态才会变成fulfilled,此时p1、p2、p3的返回值组成一个数组,传递给p的回调函数。

•只要p1、p2、p3之中有一个被rejected,p的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数。

  让我们看看下面的具体的例子:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/f1e91a881fd1efc6dec6311fade7fa74.html