Promise 的用途

515 阅读3分钟

一、Promise 的用途
Promise 是一个对象,它代表了一个异步操作的最终完成或者失败。本质上 Promise 是一个函数返回的对象,我们可以在它上面绑定回调函数,这样我们就不需要在一开始把回调函数作为参数传入这个函数了。
1、规范回调的名字或顺序
2、拒绝回调地狱,让代码可读性更强
3、更方便地捕获错误
二、如何创建一个 new Promise

return new Promise ((resolve,reject)=>{})

三、如何使用 Promise.prototype.then
then() 方法接受两个函数,成功的时候执行第一个函数,失败的时候执行第二个函数

const promise1 = new Promise((resolve, reject) => {
  resolve('Success!');
});

promise1.then((value) => {
  console.log(value);
});
  // Success!

四、如何使用 Promise.all

  • 当我们需要获得多个数据才进行下一步时使用Promise.all

Promise.all需要传入一个数组,数组中的元素都是Promise对象,当这些对象都执行成功,执行then中的第一个函数(成功函数),失败时只能获得第一个失败Promise的错误数据
Promise.all是大家一起到终点,一个失败全都失败

const promise1 = Promise.resolve(3);
const promise2 = 42;
const promise3 = new Promise((resolve, reject) => {
  setTimeout(resolve, 100, 'foo');
});

Promise.all([promise1, promise2, promise3]).then((values) => {
  console.log(values);
});
//  [3, 42, "foo"]

五、如何使用 Promise.race

  • Promise.race()返回一个 Promise,它将与第一个传递的 promise 相同的完成方式被完成。它可以是完成( resolves),也可以是失败(rejects),这要取决于第一个完成的是哪一个。
  • 如果传的迭代是空的,则返回的 promise 将永远等待。
  • 如果迭代包含一个或多个非承诺值和/或已解决/拒绝的承诺,则 Promise.race 将解析为迭代中找到的第一个值。
const promise1 = new Promise((resolve, reject) => {
  setTimeout(resolve, 500, 'one');
});

const promise2 = new Promise((resolve, reject) => {
  setTimeout(resolve, 100, 'two');
});

Promise.race([promise1, promise2]).then((value) => {
  console.log(value);
  // 哪个结果能更快获得取哪个
});
//  "two"

手写一个Promise.all

Promise.prototype.myAll
Promise.myAll = function(list){
  const results = []
  let count = 0
  return new Promise((resolve,reject) =>{
    list.map((item, index)=> {
      item.then(result=>{
          results[index] = result
          count += 1
          if (count >= list.length) { resolve(results)}
      }, reason => reject(reason) )
    })
  })
}

要点:

  1. 在 Promise 上写而不是在原型上写
  2. 用数组来记录结果
  3. 只要有一个 reject 就整体 reject

六、如何使用 Promise.catch

catch() 方法返回一个Promise,并且处理拒绝的情况,主要用于捕捉错误。它的行为与调用Promise.prototype.then(undefined, onRejected) 相同

// 抛出一个错误,大多数时候将调用catch方法
var p1 = new Promise(function(resolve, reject) {
  throw 'Uh-oh!';
});

p1.catch(function(e) {
  console.log(e); // "Uh-oh!"
});

// 在异步函数中抛出的错误不会被catch捕获到
var p2 = new Promise(function(resolve, reject) {
  setTimeout(function() {
    throw 'Uncaught Exception!';
  }, 1000);
});

p2.catch(function(e) {
  console.log(e); // 不会执行
});

// 在resolve()后面抛出的错误会被忽略
var p3 = new Promise(function(resolve, reject) {
  resolve();
  throw 'Silenced Exception!';
});

p3.catch(function(e) {
   console.log(e); // 不会执行
});

七、如何使用 Promise.finally

finally() 方法返回一个Promise。在promise结束时,无论结果是完成或者是拒绝,都会执行指定的回调函数。这为在Promise是否成功完成后都需要执行的代码提供了一种方式。
这避免了同样的语句需要在then()和catch()中各写一次的情况。

let isLoading = true;

fetch(myRequest).then(function(response) {
    var contentType = response.headers.get("content-type");
    if(contentType && contentType.includes("application/json")) {
      return response.json();
    }
    throw new TypeError("Oops, we haven't got JSON!");
  })
  .then(function(json) { /* process your JSON further */ })
  .catch(function(error) { console.log(error); })
  .finally(function() { isLoading = false; });