Sobes.tech
Junior

Как можете да обработите грешка (reject) на промиса при използване на await?

sobes.tech AI

Отговор от AI

Когато използвате await с обещание, грешките (reject) могат да бъдат обработени по няколко начина:

  1. Структура try...catch: Най-често срещаният и препоръчителен начин. Елегантно прихваща грешката, която се хвърля при решаване (resolve) или отхвърляне (reject) на обещанието.

    async function fetchData() {
      try {
        const response = await fetch('https://api.example.com/data');
        if (!response.ok) {
          throw new Error(`HTTP error! status: ${response.status}`);
        }
        const data = await response.json();
        console.log(data);
      } catch (error) {
        console.error('Грешка при получаване на данни:', error);
        // Допълнителна обработка на грешката или уведомяване на потребителя
      }
    }
    
    fetchData();
    
  2. Метод .catch() след await: По-малко предпочитан, но възможен. Грешката ще бъде обработена в callback-а .catch(), ако обещанието бъде отхвърлено.

    async function fetchData() {
      const response = await fetch('https://api.example.com/data')
        .catch(error => {
          console.error('Грешка при изпълнение на fetch:', error);
          // Обработка на грешката fetch
          throw error; // Прехвърляме грешката за по-нататъшна обработка, ако е необходимо
        });
    
      if (response && !response.ok) {
           console.error(`HTTP error! status: ${response.status}`);
           // Обработка на HTTP грешка
      }
    
      if (response && response.ok) {
          const data = await response.json()
              .catch(error => {
                  console.error('Грешка при парсиране на JSON:', error);
                  // Обработка на грешка при парсиране на JSON
              });
          if (data) {
              console.log(data);
          }
      }
    }
    
    fetchData();
    

    Този подход може да стане тромав при обработка на множество потенциални точки на отказ.

  3. Обработка с връщане на стойност на грешката: Някои библиотеки или собствени функции могат да връщат кортеж [данни, грешка] вместо отхвърляне на обещанието.

    async function safelyFetchData() {
       const [data, error] = await safePromise(fetch('https://api.example.com/data'));
       if (error) {
          console.error('Обща грешка при получаване на данни:', error);
          return null; // Или друга стойност, указваща неуспех
       }
       // Предполага се, че safePromise също обработва response.ok
       console.log(data);
       return data;
    }
    
    // Пример за реализиране на safePromise (опростено)
    async function safePromise(promise) {
        try {
            const result = await promise;
             // Тук може да има проверка result.ok за fetch
             if (result && result.ok !== undefined && !result.ok) {
                 throw new Error(`HTTP error! status: ${result.status}`);
             }
            // За fetch, може да е необходимо да изчакаме и result.json()
            if (result && typeof result.json === 'function') {
                const jsonData = await result.json();
                return [jsonData, null];
            }
            return [result, null];
        } catch (error) {
            return [null, error];
        }
    }
    
    safelyFetchData();
    

    Този модел (често наричан "error-first callback" или "go-style error handling") е удобен, когато е необходимо да се обработват грешки локално без да се прекъсва изпълнението на функцията.

Най-чистият и четим начин е използването на try...catch около блока код, съдържащ await.