今年已过半,你的promise “resolve”没

1,134 阅读6分钟

今年已过半,你的promise “resolve”没


使用 JavaScript 编写代码会大量的依赖异步计算,计算那些我们现在不需要但将来某时候可能需要的值。所以 ES6 引入了一个新的概念,用于更简单地处理异步任务:promise

promise 对象是对我们现在尚未得到但将来会得到值的占位符;它是对我们最终能够得知异步计算结果的一种保证。如果我们兑现了我们的承诺,那结果会得到一个值。如果发生了问题,结果则是一个错误,一个为什么不能交付的借口。使用 promise 的一个最佳例子是从服务器获取数据:我们要承诺最终会拿到数据,但其实总有可能发生错误。

一个 Promise 对象代表一个在这个 promise 被创建出来时不一定已知值的代理。它让你能够把异步操作最终的成功返回值或者失败原因和相应的处理程序关联起来。这样使得异步方法可以像同步方法那样返回值:异步方法并不会立即返回最终的值,而是会返回一个 promise,以便在未来某个时候把值交给使用者。

一个 Promise 必然处于以下几种状态之一:

  • 待定(pending) :初始状态,既没有被兑现,也没有被拒绝。
  • 已兑现(fulfilled) :意味着操作成功完成。
  • 已拒绝(rejected) :意味着操作失败。

待定状态的 Promise 对象要么会通过一个值被兑现,要么会通过一个原因(错误)被拒绝。当这些情况之一发生时,我们用 promise 的 then 方法排列起来的相关处理程序就会被调用。如果 promise 在一个相应的处理程序被绑定时就已经被兑现或被拒绝了,那么这个处理程序也同样会被调用,因此在完成异步操作和绑定处理方法之间不存在竞态条件。

因为 Promise.prototype.then 和  Promise.prototype.catch 方法返回的是 promise,所以它们可以被链式调用。

promises.png

附上:个人总结javascript思维导图


创建一个真实 promise 案例

const myPromise = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('foo');
  }, 300);
});

myPromise
  .then(handleResolvedA, handleRejectedA)
  .then(handleResolvedB, handleRejectedB)
  .then(handleResolvedC, handleRejectedC);

使用新的内置构造函数 Promise 来创建一个 promise 需要传入一个函数,在本例中是一个箭头函数(当然也可以简单地使用一个函数表达式)。这个函数被称为执行函数(executor function),它包含两个参数 resolvereject。当把两个内置函数:resolve 和 reject作为参数传入 Promise 构造函数后,执行函数会立刻调用。我们可以手动调用 resolve 让承诺兑现,也可以当错误发生时手动调用 reject。

代码调用 Promise 对象内置的 then 方法,我们向这个方法中传入了两个回调函数:一个成功回调函数一个失败回调函数。当承诺成功兑现(在 promise 上调用了 resolve),前一个回调就会被调用,而当出现错误就会调用后一个回调函数(可以是发生了一个未处理的异常,也可以是在 promise 上调用了 reject)。


Promise 类

Promise.all()

Promise.all() 方法接收一个promise的iterable类型(注:Array,Map,Set都属于ES6的iterable类型)的输入,并且只返回一个Promise实例, 那个输入的所有promise的resolve回调的结果是一个数组。这个Promise的resolve回调执行是在所有输入的promise的resolve回调都结束,或者输入的iterable里没有promise了的时候。它的reject回调执行是,只要任何一个输入的promise的reject回调执行或者输入不合法的promise就会立即抛出错误,并且reject的是第一个抛出的错误信息

Promise.allSettled()

该Promise.allSettled()方法返回一个在所有给定的promise都已经fulfilled或rejected后的promise,并带有一个对象数组,每个对象表示对应的promise结果。

Promise.any()

Promise.any() 接收一个Promise可迭代对象,只要其中的一个 promise 成功,就返回那个已经成功的 promise 。如果可迭代对象中没有一个 promise 成功(即所有的 promises 都失败/拒绝),就返回一个失败的 promise 和AggregateError类型的实例,它是 Error 的一个子类,用于把单一的错误集合在一起。本质上,这个方法和Promise.all()是相反的。

Promise.race()

race 函数返回一个 Promise,它将与第一个传递的 promise 相同的完成方式被完成。它可以是完成( resolves),也可以是失败(rejects),这要取决于第一个完成的方式是两个中的哪个。 如果传的迭代是空的,则返回的 promise 将永远等待。 如果迭代包含一个或多个非承诺值和/或已解决/拒绝的承诺,则 Promise.race 将解析为迭代中找到的第一个值。 Promise.race(iterable) 方法返回一个 promise,一旦迭代器中的某个promise解决或拒绝,返回的 promise就会解决或拒绝。

Promise.resolve()

Promise.resolve(value)方法返回一个以给定值解析后的Promise 对象。如果这个值是一个 promise ,那么将返回这个 promise ;如果这个值是thenable(即带有"then" 方法),返回的promise会“跟随”这个thenable的对象,采用它的最终状态;否则返回的promise将以此值完成。此函数将类promise对象的多层嵌套展平。

Promise.reject()

Promise.reject()方法返回一个带有拒绝原因的Promise对象


promise 原型方法

Promise.prototype.then()

它的作用是为 Promise 实例添加状态改变时的回调函数。前面说过,then方法的第一个参数是resolved状态的回调函数,第二个参数是rejected状态的回调函数,它们都是可选的。 then方法返回的是一个新的Promise实例(注意,不是原来那个Promise实例)。因此可以采用链式写法,即then方法后面再调用另一个then方法。

Promise.prototype.catch()

Promise.prototype.catch()方法是.then(null, rejection)或.then(undefined, rejection)的别名,用于指定发生错误时的回调函数。 catch() 方法返回一个Promise,并且处理拒绝的情况。它的行为与调用Promise.prototype.then(undefined, onRejected) 相同。

Promise.prototype.finally()

finally() 方法返回一个Promise。在promise结束时,无论结果是fulfilled或者是rejected,都会执行指定的回调函数。这为在Promise是否成功完成后都需要执行的代码提供了一种方式。 这避免了同样的语句需要在then()和catch()中各写一次的情况。 如果你想在 promise 执行完毕后无论其结果怎样都做一些处理或清理时,finally() 方法可能是有用的。


小结

最后,让我们一起加油吧!

gg.jpg

都看到这了,不如顺手点个赞再走 ( *ˇωˇ* )