
promise是什么?
Promise是异步编程的一种解决方案,比传统的回调函数和事件更合理和强大。
所谓Promise,简单来说就是一个容器,里面保存着某个未来才会结束的事情(通常是一个异步操作)。从语法上说,Promise是一个对象,从他可以获取异步操作的消息。
特点:
对象的状态不受外界影响。Promise对象代表一个异步操作,有三种状态:pending(进行中)、fulfilled(已成功)和rejected(以失败)。只有异步操作的结果可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。这也是Promise这个名字的由来。 一旦状态改变,就不会再变,任何时候都是可以得到这个结果的。Promise对象的状态改变只有两种可能:*从pending变为fulfilled和从pending变为rejected。只要这两种情况发生,状态就会凝固,不会再变了。再对Promise对象添加回调函数也会立即得到这个结果。 有了Promise对象,就可以将异步操作以同步操作的流程表达出来。 缺点:
首先无法取消Promise,一旦新建他就会立即执行,无法中途取消。其次,如果不设置回调函数,Promise内部跑出的错误无法反应到外部。当pending的时候,无法知道进展到了哪一步。
基本用法 ES6规定,Promise对象是一个构造函数,用来生成Promise实例。
下面代码创造了一个Promise实例。

resolve函数的作用是,将Promise对象的状态从"未完成"变成"成功"。(即从pending变为resolved)。在异步操作成功的时候调用,并将异步操作结果作为参数传递出去;
reject函数的作用是,将promise对象的状态从"未完成"变成"失败"(即从pending变为rejected)。在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。
Promise实例生成后,可以用then方法分别指定resolve状态和rejected状态的回调函数。

第一个回调函数是promise对象的状态变为resolved的时候调用,
第二个回调函数是promise对象的状态变为rejected时调用。
其中第二个函数是可选的,不一定需要提供。
这两个函数都接受Promise对象传出的值作为参数。

过了指定的时间以后,Promise实例的状态变为resolved,就会触发then方法绑定的回调函数。
Promise新建后就会立即执行。

- Promise.prototype.then()
Promise实例具有then方法,也就是说then方法时定义在原型对象上的。
它的作用是为Promise实例添加状态改变时的回调函数。
前面说过,then方法的第一个参数是resolved状态的回调函数,第二个参数是rejected状态的回调函数(可选)。
then方法返回的是一个新的Promise实例(注意,不是原来那个Promise实例)因此可以采用链式写法,即then方法后面再调用另一个then方法。
采用链式的then可以指定一组按照次序调用的回调函数。这时,前一个回调函数可能返回一个还是Promise对象(即有异步操作),这时候一个回调函数就会等该Promise对象的状态发生变化,才会被调用。

- Promise.prototype.catch()
Promise.prototype.catch方法是.then(null, rejection)的别名,用于指定发生错误时的回调函数。


Promise对象的错误具有冒泡性质,会一直向后传递,直到被捕获为止,也就是说错误总会被下一个catch语句捕获。
- Promise.prototype.finally()
finally方法用于指定不管Promise对象最后状态如何,都会执行的操作。
4.Pomise.all的使用
Promise.all(iterable) 方法返回一个 Promise 实例,此实例在 iterable 参数内所有的 promise 都“完成(resolved)”或参数中不包含 promise 时回调完成(resolve);如果参数中 promise 有一个失败(rejected),此实例回调失败(reject),失败原因的是第一个失败 promise 的结果。 具体代码如下: Promse.all在处理多个异步处理时非常有用,比如说一个页面上需要等两个或多个ajax的数据回来以后才正常显示,在此之前只显示loading图标。 需要特别注意的是,Promise.all获得的成功结果的数组里面的数据顺序和Promise.all接收到的数组顺序是一致的,即p1的结果在前,即便p1的结果获取的比p2要晚。这带来了一个绝大的好处:在前端开发请求数据的过程中,偶尔会遇到发送多个请求并根据请求顺序获取和使用数据的场景,使用Promise.all毫无疑问可以解决这个问题。
5、Promise.race的使用 Promise.race(iterable) 方法返回一个 promise,一旦迭代器中的某个promise解决或拒绝,返回的 promise就会解决或拒绝。 顾名思义,Promse.race就是赛跑的意思,意思就是说,Promise.race([p1, p2, p3])里面哪个结果获得的快,就返回那个结果,不管结果本身是成功状态还是失败状态。 原理是挺简单的,但是在实际运用中还没有想到什么的使用场景会使用到。 举例:超时取消 我们来看一下如何使用Promise.race来实现超时机制。 当然XHR有一个 timeout 属性,使用该属性也可以简单实现超时功能,但是为了能支持多个XHR同时超时或者其他功能,我们采用了容易理解的异步方式在XHR中通过超时来实现取消正在进行中的操作。
- 让Promise等待指定时间 首先我们来看一下如何在Promise中实现超时。 所谓超时就是要在经过一定时间后进行某些操作,使用 setTimeout 的话很好理解。 首先我们来串讲一个单纯的在Promise中调用 setTimeout 的函数。

在这里 promise对象 这个概念非常重要,请切记。 2. Promise.race中的超时 我们可以将刚才的 delayPromise 和其它promise对象一起放到 Promise.race 中来是实现简单的超时机制。


为了能区分这个 Error 对象的类型,我们再来定义一个Error 对象的子类 TimeoutError。
扩展知识:定制Error对象 Error 对象是ECMAScript的内建(build in)对象。
但是由于stack trace等原因我们不能完美的创建一个继承自 Error 的类,不过在这里我们的目的只是为了和Error有所区别,我们将创建一个 TimeoutError 类来实现我们的目的。
在ECMAScript6中可以使用 class 语法来定义类之间的继承关系。

它的使用方法和普通的 Error 对象一样,使用 throw 语句即可,如下所示。


❤️ 看完三件事
如果你觉得这篇内容对你挺有启发,我想邀请你帮我三个小忙: 点个「赞同」,让更多的人也能看到这篇内容(喜欢不点赞同,都是耍流氓 -_-) 点个关注不迷路~让我们成为长期关系 关注我的专栏(前端高级架构帮),送你高级前端面试题
文章转载至:前端进阶攻略
作者:前端进阶者