js的Promose(查漏补缺)

详细内容参考链接: ECMAscript入门.
http://es6.ruanyifeng.com/#docs/promise.

基础

  • new Promise()内部的函数是同步任务.
  • .then().cath()内部都是异步执行,所以会在同步任务全部执行完之后才会调用.
  • .then()方法指定的回调函数,如果运行中抛出错误,也会被.catch()方法捕获.
  • .catch() 等同于 .then(null/undefined, () => {})
  • Promise状态不可逆如果 Promise 状态已经变成resolved,再抛出错误是无效的。因为 Promise 的状态一旦改变,就永久保持该状态,不会再变了。
  • Promise 内部的错误不会影响到 Promise 外部的代码,通俗的说法就是“Promise 会吃掉错误”。Node.js未来会修复

Promose.prototype.finally()

  • .finally()表示不管异常与否, 必定执行(ES2018
  • .finally()方法的回调函数不接受任何参数,这意味着没有办法知道,前面的 Promise 状态到底是fulfilled还是rejected。这表明,finally方法里面的操作,应该是与状态无关的,不依赖于 Promise 的执行结果。
  • finally()本质上是then方法的特例。
  • finally()方法总是会返回原来的值。
Promise.resolve(2).finally((res) => { // 这里拿不到值
  console.log(res); // undefined
})
.then(res => { // 拿到的是.finally()之前的原来的值
  console.log(res); // 2
})

Promise.all([p1, p2, p3, …])

  • Promise.all([p1, p2, p3]) 如果p1,p2,p3不是Promise实例就会先调Promise.resolve()方法,将参数转为 Promise 实例
  • 只有p所有Promise实例的状态都变成fulfilled(成功),Promiose.all()的状态才会变成fulfilled,此时p返回值组成一个数组,传递给p的回调函数。只要p之中有一个被rejected,p的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给Promise.all()的回调函数。
const p= [
  new Promise((resolved, rejected) => { resolved(1) }),
  new Promise((resolved, rejected) => { resolved(2) }),
]
Promise.all(p).then((result) => { // 都成功数组返回Promise实例的值
    console.log(result); // [1, 2]
    
}).catch((err) => {	// 出错就返回第一个出错的Promise实例值
  console.log('错在' + err);
  
});
  • 如果作为参数的 Promise 实例,自己定义了catch方法,那么它一旦被rejected,并不会触发Promise.all()catch()方法。
const test = [
  new Promise((resolved, rejected) => {
    resolved(1)
  }),
  new Promise((resolved, rejected) => {
    rejected(2)
  }).catch(err => { // 我捕获我自己的错误
    console.log(err)
  })
]

Promise.all(test).then((result) => { // resolved 找不到第二个Promise实例的错误
  console.log(result);				// 它自己捕获了自己的错

}).catch((err) => {
  console.log('错在' + err);

});

Promise.race([p1,p2,p3])

  • Promise.race([p1,p2,p3])如果有一个改变成resolved或者rejected就执行Promise.race()之后的.thencatch 与Promise.all()很像, 也会有转换参数成Promise实例

Promise.allSettled([p1,p2,p3]) ES2020

  • Promise.allSettled([p1,p2,p3])接收一个Promise实例数组,无论数组中的实例变成resolvedrejected最终Promise.allSettled()都将执行resolved,并且返回值是一个数组
  • 返回的数组的每个成员都是一个对象,对应传入Promise.allSettled()的所有 Promise 实例。每个对象都有status属性,该属性的值只可能是字符串fulfilled或字符串rejected。fulfilled时,对象有value属性,rejected时有reason属性,对应两种状态的返回值。
const test = [
  new Promise((resolved, rejected) => {resolved(1)} ),
  new Promise((resolved, rejected) => {rejected(2)} )
]

Promise.allSettled(test).then((result) => { // 无论对错, 都会成功执行resolved()
  console.log(result);
  //  [
  //    { status: 'fulfilled', value: 1 },
  //    { status: 'rejected', reason: 2 }
//    ]

}).catch((err) => {
  console.log('错在' + err);

});

Promise.resolve()

  • Promise.resolve() 将现有对象转换成Promise对象
Promise.resolve('foo')
// 等价于
new Promise(resolve => resolve('foo'))
参数是一个 Promise 实例
  • 如果参数是 Promise 实例,那么Promise.resolve将不做任何修改、原封不动地返回这个实例。
参数是一个thenable对象
  • thenable对象指的是具有then方法的对象,比如下面这个对象。
// Promise.resolve方法会将这个对象转为 Promise 对象,然后就立即执行thenable对象的then方法。
let thenable = {
  then: function(resolve, reject) {
    resolve(42);
  }
};

let p1 = Promise.resolve(thenable); // 执行thenable内的then方法
p1.then(function(value) { // 因为调用了resolved()自然进入到.then()中
  console.log(value);  // 42
});
  • 上面代码中,thenable对象的then方法执行后,对象p1的状态就变为resolved,从而立即执行最后那个then方法指定的回调函数,输出 42。
参数不是具有then方法的对象,或根本就不是对象
  • 如果参数是一个原始值,或者是一个不具有then方法的对象,则Promise.resolve方法返回一个新的 Promise 对象,状态为resolved
const p = Promise.resolve('Hello');

p.then(function (s){
  console.log(s)
});
// Hello
  • 上面代码生成一个新的 Promise 对象的实例p。由于字符串Hello不属于异步操作(判断方法是字符串对象不具有then 方法),返回 Promise 实例的状态从一生成就是resolved,所以回调函数会立即执行。Promise.resolve方法的参数,会同时传给回调函数。
不带有任何参数
  • Promise.resolve()方法允许调用时不带参数,直接返回一个resolved状态的 Promise 对象
    所以,如果希望得到一个 Promise 对象,比较方便的方法就是直接调用Promise.resolve()方法。
const p = Promise.resolve();

p.then(function () { // resolved状态
  // ...
});
  • 上面代码的变量p就是一个 Promise 对象。
  • 需要注意的是,立即resolve()Promise 对象,是在本轮“事件循环”(event loop)的结束时执行,而不是在下一轮“事件循环”的开始时。
setTimeout(function () {
  console.log('three');
}, 0);

Promise.resolve().then(function () {
  console.log('two');
});

console.log('one');

// one
// two
// three
  • 上面代码中,setTimeout(fn, 0)在下一轮“事件循环”开始时执行,Promise.resolve()在本轮“事件循环”结束时执行,console.log(‘one’)则是立即执行,因此最先输出。

Promise.reject()

  • Promise.reject(reason)方法也会返回一个新的 Promise 实例,该实例的状态为rejected
const p = Promise.reject('出错了');
// 等同于
const p = new Promise((resolve, reject) => reject('出错了'))

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

  • 上面代码生成一个 Promise 对象的实例p,状态为rejected,回调函数会立即执行。
  • 注意,Promise.reject()方法的参数,会原封不动地作为reject的理由,变成后续方法的参数。这一点与Promise.resolve方法不一致。
const thenable = {
  then(resolve, reject) {
    reject('出错了');
  }
};

Promise.reject(thenable)
.catch(e => {
  console.log(e === thenable)
})
// true
  • 上面代码中,Promise.reject方法的参数是一个thenable对象,执行以后,后面catch方法的参数不是reject抛出的“出错了”这个字符串,而是thenable对象。也就是说他不会执行thenable对象的.then()方法
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值