Клавиша / esc

Promise.try()

Выполняет функцию и возвращает её результат как промис.

Время чтения: меньше 5 мин

Кратко

Скопировано

Метод try() — это один из статических методов объекта Promise. Метод Promise.try() оборачивает результат выполнения колбэк-функции в промис.

Пример

Скопировано

Создадим функцию handleFn(), которая обработает результаты выполнения других функций: и синхронных, и асинхронных.

        
          
          function handleFn(func){  return Promise.try(func)    .then((result) => console.log('результат:', result))    .catch((error) => console.error('ошибка:', error))}// Аргумент: асинхронная функцияhandleFn(() => Promise.resolve(42))// результат: 42// Аргумент: синхронная функцияhandleFn(() => 42)// результат: 42// Аргумент: функция, бросающая синхронную ошибкуhandleFn(() => {  throw new Error('error')})// ошибка: Error: error
          function handleFn(func){
  return Promise.try(func)
    .then((result) => console.log('результат:', result))
    .catch((error) => console.error('ошибка:', error))
}

// Аргумент: асинхронная функция
handleFn(() => Promise.resolve(42))
// результат: 42

// Аргумент: синхронная функция
handleFn(() => 42)
// результат: 42

// Аргумент: функция, бросающая синхронную ошибку
handleFn(() => {
  throw new Error('error')
})
// ошибка: Error: error

        
        
          
        
      

Как пишется

Скопировано
        
          
          Promise.try(func, arg1, arg2, ..., argN)
          Promise.try(func, arg1, arg2, ..., argN)

        
        
          
        
      

Promise.try() принимает один обязательный аргумент — функцию для вызова. Она может быть как синхронной, так и асинхронной. Остальные аргументы необязательные, это параметры для передачи в функцию.

Если вызвать Promise.try() без аргументов, будет ошибка TypeError.

Promise.try() возвращает новый промис, который будет:

  • в состоянии «выполненно» (fulfilled), если переданная синхронная функция возвращает значение;
  • в состоянии «ошибка» (rejected), если переданная синхронная функция бросает ошибку;
  • в состоянии «ожидание» (pending), если переданная функция возвращает промис.

Как понять

Скопировано

Promise.try() помогает достичь единообразия обработки результата как синхронной, так и асинхронной колбэк-функции.

Промисы позволяют удобно обрабатывать результат выполнения асинхронного кода. В случае «успеха» мы используем Promise.then(), а в случае ошибки — Promise.catch().

Предположим, у нас есть функция запроса к серверу getData():

        
          
          getData(requestData)  .then((result) => console.log('результат:', result))  .catch((error) => console.error('ошибка', error))
          getData(requestData)
  .then((result) => console.log('результат:', result))
  .catch((error) => console.error('ошибка', error))

        
        
          
        
      

Если при выполнении запроса (асинхронной операции) произойдёт ошибка, она будет корректно обработана c помощью catch(), потому что функция вернёт промис в состоянии «ошибка».

Но что произойдёт, если при выполнении getData() возникнет синхронная ошибка, например, при формировании данных для запроса? Функция не вернёт промис, а ошибка останется необработанной.

Рассмотрим на примере:

        
          
          function getData(requestData) {  // В функции отсутствует проверка типа аргумента  const url = requestData.url // ❌  return fetch(url)}// Вызов функции без параметра приведёт к ошибке TypeErrorgetData().then((result) => {  // ...}).catch((error) => {  // Ошибка не будет обработана})
          function getData(requestData) {
  // В функции отсутствует проверка типа аргумента
  const url = requestData.url // ❌

  return fetch(url)
}

// Вызов функции без параметра приведёт к ошибке TypeError
getData()
.then((result) => {
  // ...
})
.catch((error) => {
  // Ошибка не будет обработана
})

        
        
          
        
      

Чтобы единообразно обрабатывать ошибки в блоке catch нужно, чтобы функция getData() всегда возвращала промис, даже если внутри синхронный код. В этом нам поможет Promise.try():

        
          
          // Вызов функции без параметра приведёт к ошибке, но она будет обработана,// так как `Promise.try()` возвращает промисPromise.try(getData).then((result) => {  // ...}).catch((error) => {  // Обработка ошибки})
          // Вызов функции без параметра приведёт к ошибке, но она будет обработана,
// так как `Promise.try()` возвращает промис
Promise.try(getData)
.then((result) => {
  // ...
})
.catch((error) => {
  // Обработка ошибки
})

        
        
          
        
      

Альтернативы

Скопировано

Рассмотрим варианты замены Promise.try():

  1. Promise.resolve().then(func) — работает почти также, но функция func всегда начинает выполняться асинхронно.

Обратите внимание на порядок сообщений консоли:

        
          
          const func = () => console.log('1')Promise.resolve().then(func)console.log('2')// 2// 1
          const func = () => console.log('1')

Promise.resolve().then(func)
console.log('2')

// 2
// 1

        
        
          
        
      

Promise.try() позволяет выполнять синхронную функцию сразу. Это может иметь значение, когда требуется гарантированное выполнение функции без всякой задержки.

        
          
          const func = () => console.log('1')Promise.try(func)console.log('2')// 1// 2
          const func = () => console.log('1')

Promise.try(func)
console.log('2')

// 1
// 2

        
        
          
        
      
  1. new Promise(resolve => resolve(func())) — работает, как Promise.try(), но обладает более сложным синтаксисом и труднее запоминается.

Преимущества

Скопировано
  1. Нет необходимости разделять логику обработки результатов выполнения синхронных и асинхронных колбэк-функций;
  2. «Промисификация» результата выполнения колбэк-функции может быть достигнута без изменения реализации колбэк-функций;
  3. Обработка ошибок колбэк-функции может единообразно выполняться в блоке catch.
Поддержка в браузерах:
  • Chrome 128, поддерживается
  • Edge 128, поддерживается
  • Firefox 134, поддерживается
  • Safari 18.2, поддерживается
О Baseline