Как игнорировать неудавшийся запрос при использовании Promise.all?

Я создаю приложение React + Redux, и сейчас я работаю над функцией, которая извлекает определенное количество закладок пользователя на страницу.

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

Моя проблема в том, что если ресурс, отмеченный пользователем, был удален, запрос API, очевидно, приводит к ошибке 404, что приводит к ошибке Promise.all(), даже если другие запросы выполнены успешно. Итак, как я могу игнорировать ошибку этого единственного неудачного запроса и продолжать работать с успешными?

Вот моя функция:

export const fetchUserBookmarks = ( bookmarkType, reset ) => async ( dispatch, getState, api ) => {

    if ( reset ) {
        dispatch({
            type: 'RESET_BOOKMARKS'
        });
    }

    var endpoint; 

    if ( bookmarkType == 'projects' ) {

        endpoint = 'posts'; 

    } else if ( bookmarkType == 'images' ) {

        endpoint = 'media'; 

    } else {

        endpoint = bookmarkType; 

    }

    const bookmarksIDs = getState().currentUser.bookmarks.IDs[ bookmarkType ];  
    const bookmarksPerPage = getState().currentUser.bookmarks.perPage;  
    const start = bookmarksPerPage * getState().currentUser.bookmarks[ bookmarkType ].resultsPage;
    const end = start + bookmarksPerPage;   
    const bookmarksSet = bookmarksIDs.slice( start, end );      
    const BOOKMARKTYPE = bookmarkType.toUpperCase();    

    dispatch({
        type: 'IS_FETCHING_BOOKMARKED_' + BOOKMARKTYPE, 
    });     

    try {

        const bookmarks = [];

        const getBookmarks = await Promise.all(
            bookmarksSet.map( bookmarkID => 
                api.get( '/wp-json/wp/v2/' + endpoint + '/' + bookmarkID )              
            )
        ); 

        getBookmarks.map( request => { 
            bookmarks.push( request.data )
        });     

        dispatch({
            type: 'HAS_FETCHED_BOOKMARKED_' + BOOKMARKTYPE, 
            payload: bookmarks
        });                             

    } catch( error ) {

        if ( error.response !== undefined && error.response.status == 401 ) {                

            dispatch({
                type: 'IS_EMPTY_BOOKMARKED_' + BOOKMARKTYPE 
            });

        } else {

            dispatch({
                type: 'FAILED_FETCHING_BOOKMARKED_' + BOOKMARKTYPE 
            });

        }

    }

}

Можете ли вы обернуть каждое получение в обещание, а затем в catch, разрешить с сообщением, указывающим на неудачу?

nikrb 30.05.2018 12:12
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
0
1
797
2

Ответы 2

Расширяя комментарий @nikrb - вы можете отловить все 404 ошибки в своих запросах.

Не зная формата ответа API, соответствующий код может выглядеть примерно так:

const getBookmarks = await Promise.all(
  bookmarksSet.map(bookmarkID =>
    api.get('/wp-json/wp/v2/' + endpoint + '/' + bookmarkID)
      .catch((error) => {
        // avoid catching unexpected errors (not due to 404)
        if (error.statusCode !== 404) {
          throw error
        }
      })
  )
);

У меня может быть для вас хак, которым я сейчас пользуюсь. Итак, что я делаю, когда нахожусь в ситуации, о которой вы упомянули, я избегаю использования блоков try / catch, а вместо этого создаю объект результатов. В последнее время я часто использую redux-saga, поэтому больше не попадаю в такую ​​ситуацию.

В любом случае вот код, который я использую

const buildResultObject = (promise) => {
    return promise
      .then(result => ({ success: true, result }))
      .catch(error => ({ success: false, error }));
};

Promise
  .all([p1, p2, p3].map(buildResultObject))
  .then( 
    results => {
      results.map(response => {
        if (response.success) {
          console.info(response.result);
        } else {
          console.info(`Boom: ${response.error}`);
        }
      })
    }
  );

Другие вопросы по теме