ES6-promise的一些API

2019-01-15  本文已影响0人  吴高亮

接着上面的primise的基础;
在Promise实例生成过后;可调用then方法;进行相应的状态回调;

const promise=new Promise((resolve,reject)=>{
//其他操作
 if(成功){
  resolve(value);将状态改为成功的状态
 }else{
   reject(error);将状态改为失败;
 }
});
接着调用then方法;
promise.then((valuse)=>{
 //成功的回调
},(error)=>{
 //失败的回调;
});

可以看出来;then的函数接受两个参数;首先一个就是在resolve的状态下的回调函数;第二个是rejected的状态回调;第二个函数不是必传的;
另外就是then方法执行的时间是在Promise实例状态在resolve或者reject的时候才会执行then里面的方法;并且可以接受resolve(value)中的value参数;

看一个例子:

let laodeImageAsync=(url)=>{
 return new Promise(()=>{
   const image=new Image();
   image.onload=function(){
       resolve(image);
   };
   image.onerror=()=>{
     reject(new Error('Could not load image at '+ url));
   };
  return image.src=url;
 })
};

也就是在处理完成后;改变promise的状态;然后做相应的操作;

两个Promise的回调问题

如果在调用Promise的状态改变的后;会把参数给到回调函数;resolve函数出了正常的值以外;还有可能是另外一个Promise的实例;

const p1 = new Promise(function (resolve, reject) {
  setTimeout(() => reject(new Error('fail')), 3000)
})

const p2 = new Promise(function (resolve, reject) {
  setTimeout(() => resolve(p1), 1000)
})

p2
  .then(result => console.log(result))
  .catch(error => console.log(error))

上面代码中,p1是一个 Promise,3 秒之后变为rejected。p2的状态在 1 秒之后改变,resolve方法返回的是p1。由于p2返回的是另一个 Promise,导致p2自己的状态无效了,由p1的状态决定p2的状态。所以,后面的then语句都变成针对后者(p1)。又过了 2 秒,p1变为rejected,导致触发catch方法指定的回调函数。

注意,调用resolve或reject并不会终结 Promise 的参数函数的执行。

new Promise((resolve, reject) => {
  resolve(1);
  console.log(2);
}).then(r => {
  console.log(r);
});
// 2
// 1

上面代码中,调用resolve(1)以后,后面的console.log(2)还是会执行,并且会首先打印出来。这是因为立即 resolved 的 Promise 是在本轮事件循环的末尾执行,总是晚于本轮循环的同步任务。

一般来说,调用resolve或reject以后,Promise 的使命就完成了,后继操作应该放到then方法里面,而不应该直接写在resolve或reject的后面。所以,最好在它们前面加上return语句,这样就不会有意外。

then catch

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

// good
promise
  .then(function(data) { //cb
    // success
  })
  .catch(function(err) {
    // error
  });
其实在promise中rejected的状态就是catch;

finally;

finally方法用于指定不管Promise对象最后状态如何;都会执行操作;该方法是ES2018引入的标准

promise
.finally(() => {
  // 语句
});

// 等同于
promise
.then(
  result => {
    // 语句
    return result;
  },
  error => {
    // 语句
    throw error;
  }
);

上面代码中,如果不使用finally方法,同样的语句需要为成功和失败两种情况各写一次。有了finally方法,则只需要写一次。

Promise.all();

Promise.all方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。

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

p1,p2,p3都是Promise实例;p的状态由p1、p2、p3决定,分成两种情况。

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

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

// 生成一个Promise对象的数组
const promises = [2, 3, 5, 7, 11, 13].map(function (id) {
  return getJSON('/post/' + id + ".json");
});

Promise.all(promises).then(function (posts) {
  // ...
}).catch(function(reason){
  // ...
});

Promise.race();

Promise.race()方法是将多个Promise实例包装为一个实例;
const p = Promise.race([p1, p2, p3]);
上面代码中,只要p1、p2、p3之中有一个实例率先改变状态,p的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给p的回调函数。

Promise.race方法的参数与Promise.all方法一样,如果不是 Promise 实例,就会先调用下面讲到的Promise.resolve方法,将参数转为 Promise 实例,再进一步处理

上一篇下一篇

猜你喜欢

热点阅读