Повторное изучение внешнего интерфейса - подробное объяснение использования промисов

JavaScript
Повторное изучение внешнего интерфейса - подробное объяснение использования промисов

предисловие

В мире JavaScript Promise, несомненно, является знаковым изменением: он не только решает проблему глубоко вложенных функций обратного вызова в асинхронном программировании, но и закладывает основу для Async/Await.

Спецификация Promise была впервые предложена сообществом CommonJS, а позже стала спецификацией языка ES2015 (ES6) и, можно сказать, стала предпочтительным решением для асинхронного программирования.
Далее в этой статье будут подробно описаны функции и методы Promise для справки.Если в тексте есть какие-либо неточности, вы можете их исправить.
Без лишних слов, давайте будем талантливыми!

текст

1. Обещание конструктора (исполнитель)

  • исполнитель:
    • Конструктор Promise принимает в качестве параметра исполняющую программу (исполнитель на самом деле является функцией обратного вызова).При выполнении конструктора Promise входящий исполнитель будет выполнен немедленно.
    • При вызове функции excutor в качестве параметров передаются две функции, resolve и reject; при вызове функции resolve состояние Promise меняется на выполнено (completed); при вызове функции reject состояние Promise меняется на reject (не удалось)
    • Если внутри экскутора возникает исключение, состояние Promise будет напрямую изменено на отклонено, а в качестве результата будет возвращен объект ошибки.
const p = new Promise((resolve, reject) => {
  console.log("excutor函数会被立即执行");
  resolve("状态变更为:fulfilled");
  // reject("状态变更为:rejected");
  // throw new Error('报错,Promise状态将直接变更为rejected')
});

2. Статус

В Promise есть 3 состояния:

  • **ожидание: **исходное состояние, ни успеха, ни отказа
  • **выполнено: **успешно
  • rejected:потерпеть неудачу

3. Метод экземпляра

- then(onFulfilled, onRejected)

  • эффект:
    • Зарегистрируйте обратные вызовы onFulfilled и onRejected для Promise
    • Возвращает новое обещание для реализации связанных вызовов
    • Новое обещание будет разрешено с возвращаемым значением функции обратного вызова.
  • характеристика:
    • Сам метод then автоматически вернет новый объект Promise, конечно, вы также можете вручную вернуть объект Promise в любой функции обратного вызова (onFulfilled или onRejected).
const p = new Promise((resolve, reject) => {
  console.log("excutor函数会被立即执行");
  resolve("状态变更为:fulfilled");
});

// then方法本身会返回一个promise
p.then()
  .then()
  .then((res) => {
    console.log(res); //输出:状态变更为:fulfilled
  });
// then方法通过回调函数可以返回promise
p.then(
  (res) => {
    return new Promise((resolve, reject) => {
      resolve("onFulfilled中返回的Promise");
    });
  },
  (reason) => {
    return new Promise((resolve, reject) => {
      resolve("onRejected回调中也可以返回Promise");
    });
  }
).then((res) => {
  console.log(res);
});
  • Метод then можно связать с возвращаемым объектом Promise.
  • Если функция обратного вызова возвращает нормальное значение, оно будет получено в качестве параметра функции обратного вызова в следующем, а затем
  • Если функция обратного вызова возвращает промис, то следующий метод будет ждать завершения выполнения промиса и получит результат выполнения промиса.
const p2 = new Promise((resolve, reject) => {
  console.log("excutor函数会被立即执行");
  resolve("状态变更为:fulfilled");
});
p2.then(res => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve('promise执行完毕')
    }, 1000);
  })
}).then(res => {
  console.log(res)//等待1秒钟,输出:promise执行完毕
})
  • Если функция обратного вызова не передана, Promise автоматически зарегистрирует функцию обратного вызова для метода then, вернет полученное значение в функцию обратного вызова и передаст его следующему объекту then для реализации проникновения значения.
没有给then注册回调,发生值穿透
const p3 = new Promise((resolve, reject) => {
  resolve(1);
});
p3.then(2).then(4).then(console.log); //1

  • Объект обещания, возвращаемый сам по себе, не допускается в качестве возвращаемого значения в методе then
const p4 = p3.then(res => {
  // 不允许,将会报错
  // TypeError: Chaining cycle detected for promise #<Promise>
  return p4
})

- catch(onRejected)

  • эффект
    • Добавить обратный вызов onRejected в Promise
  • характеристика
    • возвращает новое обещание
    • Новое обещание будет разрешено с возвращаемым значением функции обратного вызова.
const promise = new Promise((resolve, reject) => {
  reject(100);
});
promise
  .catch((reason) => {
    console.log(reason); //100
    return 200; //catch函数返回值将作为新Promise的resolve结果
  })
  .then((res) => {
    // 新Promise执行结果
    console.log(res); //200
  });

- finally(finallyCallback)

  • эффект
    • Добавьте функцию обратного вызова обработчика событий в Promise
  • характеристика
    • Входящий finallyCallback вызывается в случае успеха или неудачи
    • finallyCallback вернет новое обещание
    • Результат выполнения промиса не может быть получен внутри finallyCallback
const promise = new Promise((resolve, reject) => {
  resolve(100);
});
promise
  .finally((res) => {
    console.log("finally回调函数无论成功或者失败,始终会被执行");
    // finally回调函数内获取不到promise执行结果
    console.log(res);
  })
  .then((res) => {
    // finally回调函数返回一个新的promise,实现链式调用
    console.log(res);
  });

4. Статический метод

- Promise.all(promiseArray)

  • эффект:
    • Принимает массив в качестве параметра и возвращает результаты выполнения в формате массива
    • Одновременно выполнять обещания объектов в массиве
  • характеристика:
    • Принимает в качестве параметра массив, элементы массива могут быть обычными значениями или объектами промисов
    • Результат выполнения возвращается в виде массива, а элементы массива соответствуют один к одному пришедшему promiseArray
    • Если элементы входящего массива являются обычными значениями, поместите соответствующие значения непосредственно в результирующий массив, как они есть
    • Если элементы входящего массива являются объектами промисов, соответствующие объекты промисов будут выполняться одновременно, ждать окончания выполнения и возвращать результат
const promise1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve("p1");
  }, 2000);
});
const promise2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve("p2");
  }, 1000);
});

const promiseAll = Promise.all([1, 2, promise1, 3, 4, promise2, 5]);
promiseAll.then((res) => {
  //并发执行promise
  //执行结果与传入的数组一一对应
  //会等待所有任务执行完毕之后统一返回结果
  console.log(res); //[1,2,"p1",3,4,"p2",5]
});
  • Если элемент во входящем массиве не может быть выполнен, обещание не будет выполнено.
const promise1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve("p1");
  }, 2000);
});
const promise2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject('我这该死的温柔,居然执行失败了')
  }, 1000);
});

const promiseAll = Promise.all([1, 2, promise1, 3, 4, promise2, 5]);
promiseAll.then((res) => {
  // 任何一个任务执行失败 ,整个promise将执行失败
  console.log(res);
}).catch(e => {
  //任何一个任务失败,将导致整个Promise执行失败
  console.log('fail',e)
});

- Promise.allSettled(promiseArray)

Неофициальная версия, в настоящее время находится на этапе 4, еще не полностью поддерживается браузерами.

  • эффект:
    • То же, что и Promise.all
  • характеристика:
    • Дождитесь завершения всех задач в массиве, верните массив
    • Независимо от успеха или неудачи, будет обратный результат
    • Остальные такие же, как Promise.all
const promise1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve("p1");
  }, 2000);
});
const promise2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject("我这该死的温柔,居然执行失败了");
  }, 1000);
});

const promiseAll = Promise.allSettled([1, 2, promise1, 3, 4, promise2, 5]);
promiseAll
  .then((res) => {
    /**
     Promise.allSettled执行结果
    [
      { status: 'fulfilled', value: 1 },
      { status: 'fulfilled', value: 2 },
      { status: 'fulfilled', value: 'p1' },
      { status: 'fulfilled', value: 3 },
      { status: 'fulfilled', value: 4 },
      { status: 'rejected', reason: '我这该死的温柔,居然执行失败了' },
      { status: 'fulfilled', value: 5 }
    ]
   */
    console.log(res);
  })
  .catch((e) => {
    console.log("fail", e);
  });

- Promise.race(promiseArray)

  • эффект
    • Принимать массив и одновременно выполнять задачи в массиве
    • Тот, кто выполняет блок, возвращает результат того, кто преуспевает или терпит неудачу
    • Обычно используется для функции тайм-аута сети
const promise1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve("p1");
  }, 2000);
});
const promise2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve("p2");
  }, 1000);
});
const promise3 = new Promise((resolve, reject) => {
  // 假设500毫秒后网络超时
  setTimeout(() => {
    reject("超时了");
  }, 500);
});

const promiseRace = Promise.race([promise1, promise2, promise3]);
promiseRace
  .then((res) => {
    console.log(res);
  })
  .catch((e) => {
    // 谁执行块,就返回谁
    console.log("fail", e);
  });

- Promise.reject(reason)

  • эффект:
    • Возвращает невыполненное обещание и передает информацию об ошибке соответствующему методу обработки.
Promise.reject("rejected")
  .then((res) => {
    console.log('value', res);
  })
  .catch((reason) => {
    // reason rejected
    console.log('reason', reason);
  });

- Promise.resolve(value)

  • эффект:
    • Принимает значение и возвращает обещание
  • характеристика:
    • Если значение является обычным значением, используйте обычное значение в результате разрешения нового промиса.
    • Если значение является обещанием, вернуть значение как есть
Promise.resolve(100).then((res) => {
  console.log(res); //100
});

const promise = new Promise((resolve, reject) => {
  reject(200);
});
promise
  .then((res) => {
    console.log(res); //200
  });

Суммировать

На этом этапе использование Promise подводится итог.Спасибо за чтение, и я надеюсь, что это будет полезно для вас. Если у вас есть какие-либо идеи, перейдите в область комментариев и скажите об этом, давайте обсудим и добьемся прогресса вместе.
Поняв, как использовать промисы, в следующей статье я объясню основные принципы промисов, написав исходный код.