ES6精通之Promise个人笔记

2019-12-17Promise

目录

  • Promise 对象的简介和特点
  • Promise.prototype.then()
  • Promise.prototype.catch()
  • Promise.prototype.finally()
  • Promise.all()
  • Promise.race()
  • Promise.allSettled()
  • Promise.resolve()
  • Promise.reject()

Promise 对象的简介和特点
  1. Promise只有三种状态:pending,resolved,rejected
  2. 一旦状态改变就无法再次变化,只有pending->resolved 或 pending->rejected两种方式
  3. 一旦创建了Promise就会立即执行无法取消,如果不设置回调函数,Promise内部的错误不会反映到外部
  4. 如果某些事情不断反复发生,使用Stream要比Promise更好用
基本用法
const promise = new Promise(function(resolve, reject) {
  // ... some code

  if (/* 异步操作成功 */){
    resolve(value);
  } else {
    reject(error);
  }
});

resolve() 把pending状态变为resolved状态,reject() 把pending状态变为rejected状态
实例:封装异步加载图片

function loadImageAsync(url) {
  return new Promise(function(resolve, reject) {
    const 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()函数中的参数会作为回调函数的参数来进行使用

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

注意:resolve()和reject()并不会终止函数的执行,所以最好在resolve()或reject()前面加上return

Promise.prototype.then()

then方法返回的是一个新的Promise实例(注意,不是原来那个Promise实例)。因此可以采用链式写法

getJSON("/posts.json").then(function(json) {
  return json.post;
}).then(function(post) {
  // ...
});
Promise.prototype.catch()
  1. 一般接收回调方法
promise.then(function(value) {
  // success
}, function(error) {
  // failure
});

错误会被回调的err函数捕获

2.catch写法

const promise = new Promise(function(resolve, reject) {
  throw new Error('test');
});
promise.catch(function(error) {
  console.log(error);
});

注意:如果在resolve()后面再抛出错误不会被catch捕获,因为这时候pending的状态已经被改变,不会再次改变

3.Promise的错误具有冒泡性质,就是错误一直向后传递,直到被捕获为止

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

4.和传统的try…catch不同,如果Promise没有使用catch,Promise抛出的错误不会有任何反应,也不会阻挡程序的执行

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

Promise.resolve()
.catch(function(error) {
  console.log('oh no', error);
})
.then(function() {
  console.log('carry on');
});
//carry on

因为没有抛出错误,所以直接执行了后面的then方法,换成reject()抛出错误会执行catch和then方法

6.catch方法之中,还能再抛出错误。抛出的错误将会被下一个catch接收

Promise.prototype.finally()

不管Promise最后的状态如何,都会执行finally方法,并且不接受任何参数

Promise.all()

将多个Promise实例包装成一个Promise实例,Promise.all的参数可以不是数组,但是必须要有Iterator接口

要点
  1. Promise中的可遍历对象之后全都是resolve()才会触发Promise.all().then()方法,否则触发.chath方法
  2. 如果Promise.all中的数组中某一个实例reject(),但是该实例被自身的catch捕获了,则执行完实例的reject()方法后也会编程resolve()
const p1 = new Promise((resolve, reject) => {
  resolve('hello');
})
.then(result => result)
.catch(e => e);

const p2 = new Promise((resolve, reject) => {
  throw new Error('报错了');
})
.then(result => result)
.catch(e => e);

Promise.all([p1, p2])
.then(result => console.log(result))
.catch(e => console.log(e));
// ["hello", Error: 报错了]
//如果p2没有catch方法,则会被Promise.all()捕获
Promise.race()
const p = Promise.race([p1, p2, p3]);

p1,p2,p3三个Promise实例中哪个先返回resolve,则race().then的参数就是先返回的那个参数,只有全部reject()后才会触发rece().catch()方法

Promise.allSettled()

接收一个可遍历对象作为参数,之后所有的可便利对象都返回结果时候才会执行then

const resolved = Promise.resolve(42);
const rejected = Promise.reject(-1);

const allSettledPromise = Promise.allSettled([resolved, rejected]);

allSettledPromise.then(function (results) {
  console.log(results);
});
// [
//    { status: 'fulfilled', value: 42 },
//    { status: 'rejected', reason: -1 }
// ]
Promise.resolve()

作用:将现有的对象转换为Promise对象

Promise.resolve('foo')
// 等价于
new Promise(resolve => resolve('foo'))

参数分为四种情况:

  1. 参数是一个Promise实例,那么Promise.resolve()不会做任何修改,原封不动的返回这个实例
  2. 参数是一个thenable对象,Promise.resolve()会将这个对象转换为Promise对象,然后立即执行thenable中的then方法
let thenable = {
  then: function(resolve, reject) {
    resolve(42);
  }
};

let p1 = Promise.resolve(thenable);
p1.then(function(value) {
  console.log(value);  // 42
});

3.参数不是具有then方法的对象,或根本不是对象,则Promise.resolve()返回的是一个新的Promise对象,状态是resolve()

const p = Promise.resolve('Hello');

p.then(function (s){
  console.log(s)
});
// Hello

4.不带有任何参数,直接返回一个resolved状态的 Promise 对象。

const p = Promise.resolve();

p.then(function () {
  // ...
});
Promise.reject()

Promise.reject()返回的也是一个Promises实例,该实例的状态是rejected()

const p = Promise.reject('出错了');
// 等同于
const p = new Promise((resolve, reject) => reject('出错了'))

p.then(null, function (s) {
  console.log(s)
});
// 出错了

Promise.reject()的参数和resolve方法不同,会原封不动的被catch接收

const thenable = {
  then(resolve, reject) {
    reject('出错了');
  }
};

Promise.reject(thenable)
.catch(e => {
  console.log(e === thenable)
})
// true

参考文献
阮一峰官网(ES6 Promise对象)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值