使用Promise.all时如何忽略失败的请求?

时间:2018-05-30 09:46:06

标签: reactjs redux promise

我正在构建一个React + Redux应用程序,我现在正在开发一个每页获取一定数量用户书签的函数。

它是这样的:当用户为资源添加书签时,资源的ID存储在数据库中并与用户相关联。因此,我正在处理的函数获取用户书签的ID,并发出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 
            });

        }

    }

}

2 个答案:

答案 0 :(得分:0)

扩展@ 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
        }
      })
  )
);

答案 1 :(得分:0)

我可能有一个我正在使用的黑客。所以,当我处于你提到的情况时,我会做什么,我避免使用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.log(response.result);
        } else {
          console.log(`Boom: ${response.error}`);
        }
      })
    }
  );