前端面试题之promise

183 阅读3分钟

promise的含义

Promise是异步编程的解决方案,解决了回掉地狱的问题(将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。)。 它是一个容器,里面存了异步操作,它可以获取异步操作的消息。

两个特点

  1. 有三种状态,pending(进行中)、fulfilled(已成功)和rejected(已失败)。对 象的状态不受外界影响。
  2. 一旦状态改变,就不会在变。从pendingfulfilled和从pendingrejected

三个缺点

  1. 无法取消,一旦新建就会立即执行,无法中途取消
  2. 如果不设置回调函数,promise内部抛出的错误,不会反应到外部
  3. 当处于pending(进行中)状态时,无法得知目前进展到哪一个阶段

promise实例原型上的三个方法(then、catch、finally)

(1) Promise.prototype.then()

then方法可以接受两个回调函数作为参数。第一个回调函数是Promise对象的状态变为resolved时调用,第二个回调函数是Promise对象的状态变为rejected时调用。这两个函数都是可选的,不一定要提供。它们都接受Promise对象传出的值作为参数。 简单说:then接受两个回调函数作为参数,一个是resolved,一个是rejected,可选。非必填。

(2) Promise.prototype.catch()

catch方法相当于是.then的rejected参数,发生错误时的回调函数

getJSON('/posts.json').then(function(posts) {
  // ...
}).catch(function(error) {
  // 处理 getJSON 和 前一个回调函数运行时发生的错误
  console.log('发生错误!', error);
});

上面代码中,getJSON()方法返回一个 Promise 对象,如果该对象状态变为resolved,则会调用then()方法指定的回调函数;如果异步操作抛出错误,状态就会变为rejected,就会调用catch()方法指定的回调函数,处理这个错误。 then()方法指定的回调函数,如果运行中抛出错误,也会被catch()方法捕获。下面是一个例子。

const promise = new Promise(function(resolve, reject) {
  throw new Error('test');
});
promise.catch(function(error) {
  console.log(error);
});
// Error: test

如果 Promise 状态已经变成resolved,再抛出错误是无效的。

const promise = new Promise(function(resolve, reject) {
  resolve('ok');
  throw new Error('test');//ok已经抛出,所以这一行不会在执行了
});
promise
  .then(function(value) { console.log(value) })
  .catch(function(error) { console.log(error) });
// ok

上面代码中,Promise 在resolve语句后面,再抛出错误,不会被捕获,等于没有抛出。因为 Promise 的状态一旦改变,就永久保持该状态,不会再变了。

(3) Promise.prototype.finally()

finally()方法不管 Promise 对象最后状态如何,都会执行的操作。

promise
.then(result => {···})
.catch(error => {···})
.finally(() => {···});

上面代码中,不管promise最后的状态,在执行完thencatch指定的回调函数以后,都会执行finally方法指定的回调函数。 finally方法的回调函数不接受任何参数,不知道前面的promise状态时失败还是成功,

三个方法.all .race

(1) Promise.all()

Promise.all()方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。

const p = Promise.all([p1, p2, p3]);

Promise.all()方法接受一个数组作为参数,只有all中的所有状态都是成功的,p的状态才是成功,有一个失败,就是失败的状态 Promise.all()方法只适合所有异步操作都成功的情况

(2) Promise.race()

Promise.race()方法同样是将多个 Promise 实例,包装成一个新的 Promise 实例。

const p = Promise.race([p1, p2, p3]);

谁先改变状态,返回的状态就是谁

(3) Promise.allSettled()

接受数组作为参数,所有的异步操作都请求结束,才会继续执行下面的代码,返回所有异步操作的结果,返回的结果数组形式。 状态总是fulfilled,不会变成rejected

const resolved = Promise.resolve(42);
const rejected = Promise.reject(-1);

const allSettledPromise = Promise.allSettled([resolved, rejected]);

allSettledPromise.then(function (results) {
  console.log(results);
});
// [
//    { status: 'fulfilled', value: 42 },
//    { status: 'rejected', reason: -1 }
// ]