JavaScript--关于Promise该了解些什么

Promise是解决异步编程的解决方案,比传统的回调解决方案,要更加强大合理。所谓Promise,其实就是一个容器,保存在未来才会结束的事件。从语法上讲,Promise是一个对象。他有俩个特点:
(1)Promise的状态不受外界影响,Promise是一个异步操作,有三种状态,padding,fulfilled, rejected.只有异步操作的结果,可以决定当前的状态是哪一种?任何其他操作都无法改变这个状态。
(2)一旦状态改变就不会再变。任何时候都可以得到这个结果。只能从padding到fulfilled,从padding到rejected.
Promise也有缺点:
(1)一旦创建,就无法取消。创建就会立即执行,无法中途取消。
(2)如果不设置回调,那么Promise内部的错误不会反映到外部。
(3)当Promise处于padding状态的时候,并不能确认进行到什么阶段。
Promise的一些方法:

Promise.prototype.then()

then()方法定义在原型上,他的作用是为Promise实例添加状态时的回调函数。可以有俩个为function的参数,第一个为resolved状态的回调,第二个为rejected状态的回调,他们都是可选的。then()返回一个新的Promise,注意不是原来的那个实例,因此可以采用链式调用,后面接着then()

Promise.prototype.catch()

Promise.prototype.catch()方法是.then(null, rejection)或.then(undefined, rejection)的别名,用于指定发生错误时的回调函数。then()方法指定的回调函数,如果运行中抛出错误,也会被catch()方法捕获。如果then()方法的错误被下一个then()方法的第二个参数捕获,则不会被catch()捕获。。如果 Promise 状态已经变成resolved,再抛出错误是无效的。如果没有使用catch()方法处理错误,那么Promise对象跑出的错误不会传递到外层。另外需要注意的是:在链式调用中,如果前面的then()方法并没有错误,那么就会跳过后面的catch()方法,继续执行后面的then()方法,如果这是出现错误只能被其后面的catch捕获,与前面的catch()无关。还有,当在catch()方法中跑出错误时,本身是不能捕获到错误的,只能是后面的catch()来捕获。

Promise.prototype.finally()

finally()方法的执行,与Promise的状态无关。finally()方法,旨在与不管promise对象最后的状态是什么都会执行的操作。finally方法的回调函数不接受任何参数,这意味着没有办法知道,前面的 Promise 状态到底是fulfilled还是rejected。这表明,finally方法里面的操作,应该是与状态无关的,不依赖于 Promise 的执行结果。

Promise.all()

Promise.all()的参数是一个数组,数组中是一个个Promise实例。当数组中所有的Promise实例的状态都变成fulfilled,Promise的状态才会变成fulfilled,此时返回值是一个数组。反之,只要有一个状态是rejected,那么Promise的状态就会变成rejected,此时返回值是第一个被rejected的实例的返回值。
如果某个promise实例是rejected,但是同时有自己的catch(),那么相对于Promise.all()并不会是rejected状态。而应该是正常返回到Promise.all()的fulfilled状态。

Promise.race()

Promise.race()和Promise.all()相似,他们区别在于。Promise.race()中的Promise实例,只要有一个状态发生变化,那么Promise.race()的状态就会发生变化。

Promise.allSettled()

Promise.allSettled()方法接受一组 Promise 实例作为参数,包装成一个新的 Promise 实例。只有等到所有这些参数实例都返回结果,不管是fulfilled还是rejected,包装实例才会结束。一旦结束,状态总是fulfilled,不会变成rejected。状态变成fulfilled后,Promise 的监听函数接收到的参数是一个数组,每个成员对应一个传入Promise.allSettled()的 Promise 实例。
Promise.allSettle()的最大用处在于:他可以返回所有Promise的结果。

Promise.any()

该方法接受一组 Promise 实例作为参数,包装成一个新的 Promise 实例返回。只要参数实例有一个变成fulfilled状态,包装实例就会变成fulfilled状态;如果所有参数实例都变成rejected状态,包装实例就会变成rejected状态。

Promise.any()跟Promise.race()方法很像,只有一点不同,就是Promise.any()不会因为某个 Promise 变成rejected状态而结束,必须等到所有参数 Promise 变成rejected状态才会结束。

Promise.resolve()

Promise.resolve()的作用是将现有对象转化为Promise对象。
(1)参数是一个Promise对象
此时,什么都不做,返回原来的Promise对象
(2)参数是一个thenable对象

1
2
3
4
5
let thenable = {
then: function(resolve, reject) {
resolve(42);
}
};

Promise.resolve()方法会将这个对象转为 Promise 对象,然后就立即执行thenable对象的then()方法。
(3)参数不是具有then()方法的对象,或根本就不是对象
如果参数是一个原始值,或者是一个不具有then()方法的对象,则Promise.resolve()方法返回一个新的 Promise 对象,状态为resolved。
(4)Promise.resolve()方法允许调用时不带参数,直接返回一个resolved状态的 Promise 对象。所以,如果希望得到一个 Promise 对象,比较方便的方法就是直接调用Promise.resolve()方法。

Promise.reject()

Promise.reject(reason)方法也会返回一个新的 Promise 实例,该实例的状态为rejected。后面可以接catch()方法。

Promise.try()

Promise.try()方法有点像try{}catch{}的用法,可以让同步函数,同步执行,异步函数,异步执行的时候,对于抛出的错误可以捕获。

1
2
3
Promise.try(() => database.users.get({id: userId}))
.then(...)
.catch(...)

Promise的应用

加载图片,一旦加载完成,Promise的状态就发生改变。

1
2
3
4
5
6
7
8
const preloadImage = function (path) {
return new Promise(function (resolve, reject) {
const image = new Image();
image.onload = resolve;
image.onerror = reject;
image.src = path;
});
};
  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!
  • Copyrights © 2015-2022 Lee
  • 访问人数: | 浏览次数:

请我喝杯咖啡吧~

支付宝
微信