promise的三种状态: pending(进行中)、fulfilled(已成功)和rejected(已失败)(一旦状态改变,就不会再变)。非异步。 一旦新建它就会立即执行,无法中途取消。
Promise是一个构造函数,用来实例化一个Promise实例。这个Promise构造函数,用一个函数来作为参数,这个作为参数的函数有两个参数,第一个参数是resolve,第二个参数是reject,都是必填项。
异步是一个耗时的过程,当在执行异步的时候,就是Promise的等待过程,当异步函数执行完,如果异步执行成功,就调用resolve,将等待切换到成功,如果异步执行失败,我就调用reject,将等待切换到失败。
注意:在promise的then()中存放着异步函数,所有的异步都存在于js的任务队列中,当js的主线程执行完毕后,会依次执行任务队列中的内容。
then:方法可以有两个参数(第二个可选),第一个是resolve状态的回调函数第二个是reject状态的回调函数(可选)
then方法返回的是一个新的Promise实例(不是原来那个Promise实例),Promise返回的resolve和reject,这两个参数分别和then方法的两个参数对应。当省略第二个参数时,catch的存在就很有意义 。
如果前一个Promise对象是resolve状态,则后一个Promise对象执行第一个参数方法(resolve),如果前一个Promise对象是reject状态,则后一个Promise对象执行第二个参数方法(reject),如果前一个Promise对象抛出异常(throw error),则后一个Promise对象执行第二个参数方法(reject),如果前一个Promise对象返回具体的值,则此数值将作为后一个Promise对象的输入,执行第一个参数方法(resolve),如果前一个Promise对象没有返回状态(resolve或者reject),也没有抛错(throw error),也没有返回具体数值,我们则认为它返回 了一个undefined,则undefined将作为后一个Promise对象的输入,执行第一个参数方法resolve。
catch:catch就是then方法的语法糖,catch方法是.then(null, rejection)或.then(undefined, rejection)的别名,也就是说,catch也是then,它用于捕获错误,它的参数也就是then的第二个参数。 如果不写第二个参数,执行了reject后,会进入catch中的。
输出: //我在主线程 //我是异步执行的失败:失败啦
重点: promise同样也存在局限,例如:
1. throw new Error('error'); console.log('不会执行这里');因为 throw error 的缘故,代码被阻断执行,并不会打印 “不会执行这里”
2. const promise = new Promise(null);console.log('不会执行这里');这是因为通过无效的方式使用 Promise,并且出现了一个错误阻碍了正常 Promise 的构造,结果会得到一个立刻抛出的异常,而不是一个被拒绝的 Promise。
3. let promise = new Promise(() => { throw new Error('error')});console.log('不会执行这里'); 这次会正常的打印 “不会执行这里”,说明 Promise 内部的错误不会影响到 Promise 外部的代码。
其实这并不是 Promise 独有的局限性,try..catch 也是这样,同样会捕获一个异常并简单的吃掉错误。
而正是因为错误被吃掉,Promise 链中的错误很容易被忽略掉,这也是为什么会一般推荐在 Promise 链的最后添加一个 catch 函数,因为对于一个没有错误处理函数的 Promise 链,任何错误都会在链中被传播下去。
Promise.all():
Promise.all就是用于将多个 Promise 实例,包装成一个新的 Promise 实例。
Promise.all,接收一个数组作为参数,数组的每一项都返回Promise实例。
p1,p2,p3都是返回promise实例,Promise.all不关心他们的执行顺序。
如果他们都返回成功的状态,Promise.all则返回成功的状态,输出一个数组,是这三个p1,p2,p3的返回值,数组的顺序和他们的执行顺序无关,和他们作为参数排列的顺序有关。可以进行人为进行控制。
如果有一个返回失败(reject),Promise.all则返回失败(reject)的状态,此时第一个被reject的实例的返回值,会传递给P的回调函数。三个promise实例参数之间是“与”的关系,全部成功,Promise.all就返回成功,有一个失败,Promise.all就返回失败
Promise.race():
Promise中的竞态,用法和Promise.all类似,对应参数的要求和Promise.all相同,传入一个数组作为参数,参数要返回一个Promise实例。
race就是竞争的意思,数组内的Promise实例,谁执行的快,就返回谁的执行结果,不管是成功还是失败。
p1是第一个完成的,所以p的返回结果就是p1的执行结果,而且即使完成,进程是不会立即停止,还会继续执行下去。
Promise.finally():
finally方法用于指定不管 Promise 对象最后状态如何,都会执行的操作。该方法是 ES2018 引入标准的。