代码之家  ›  专栏  ›  技术社区  ›  lmcarreiro

如何在新的js async/await语法中使用redux thunk中间件异步操作

  •  0
  • lmcarreiro  · 技术社区  · 8 年前

    我试图理解redux中的异步操作。阅读 this page 我得到了下面的例子:

    export function fetchPosts(subreddit) {
      return (dispatch) => {
    ​
        dispatch(requestPosts(subreddit))
    ​
        return fetch(`https://www.reddit.com/r/${subreddit}.json`)
          .then(
            response => response.json(),
            // Do not use catch, because that will also catch
            // any errors in the dispatch and resulting render,
            // causing a loop of 'Unexpected batch number' errors.
            // https://github.com/facebook/react/issues/6895
            error => console.log('An error occurred.', error)
          )
          .then(json =>
            dispatch(receivePosts(subreddit, json))
          )
      }
    }
    

    关于那个评论,吞咽react异常是一个常见的错误,我试图避免的是。。。我正在尝试使用新的javascript异步/等待语法。。。具有完全相同行为的等效代码是什么?

    我首先想到的是:

    export function fetchPosts(subreddit) {
    ​
      return async (dispatch) => {
    
        dispatch(requestPosts(subreddit));
        try {
          const response = await fetch(`https://www.reddit.com/r/${subreddit}.json`);
          const json = await response.json();
          dispatch(receivePosts(subreddit, json));
        }
        catch (error) {
          console.log('An error occurred.', error);
        }
      }
    }
    

    但我有种感觉,这正是评论告诉我要避免的。然后我想到了这个密码:

    export function fetchPosts(subreddit) {
    ​
      return async (dispatch) => {
    
        dispatch(requestPosts(subreddit));
    
        try {
          const response = await fetch(`https://www.reddit.com/r/${subreddit}.json`);
          const json = await response.json();
        }
        catch (error) {
          console.log('An error occurred.', error);
          return;
        }
    
        dispatch(receivePosts(subreddit, json));
      }
    }
    

    但是在出现错误的情况下,我不确定行为是否与没有async/await的示例相同。我不确定是否需要 return 在里面 catch 封锁。这个例子返回了一个承诺,我不确定我的代码是否还会发生这种情况。

    我四处寻找,才发现 this question 但是没有回应,我发现 redux-saga 使用生成器/屈服语法的组件。我应该使用redux saga而不是redux thunk和async/await?

    2 回复  |  直到 8 年前
        1
  •  1
  •   Bergi    8 年前

    我觉得原来的代码应该是

    export function fetchPosts(subreddit) {
      return (dispatch) => {
        dispatch(requestPosts(subreddit));
        return fetch(`https://www.reddit.com/r/${subreddit}.json`)
          .then(response =>
            response.json()
          )
          .then(json =>
            dispatch(receivePosts(subreddit, json))
          , error => {
            // Do not use catch, because that will also catch
            // any errors in the dispatch and resulting render,
            // causing a loop of 'Unexpected batch number' errors.
            // https://github.com/facebook/react/issues/6895
            console.log('An error occurred.', error)
          });
      }
    }
    

    其中错误处理程序是 可供替代的 派遣 receivePosts(subreddit, json) ,而不是JSON解析的替代方法(并且无条件地后面跟着可能未定义的 json 价值)。

    这种分支 is hard to achieve with try / catch when using async / await ,所以我会保留 then 语法。如果你想重写它,你的第二次尝试是好的(相当于我的更正 然后 语法),但您需要声明 json格式 尝试 阻止(或使用 var 而不是 const ):

    export function fetchPosts(subreddit) {
      return async (dispatch) => {
        dispatch(requestPosts(subreddit));
        let json;
    //  ^^^^^^^^
        try {
          const response = await fetch(`https://www.reddit.com/r/${subreddit}.json`);
          json = await response.json();
        } catch (error) {
          console.log('An error occurred.', error);
          return;
        }
        dispatch(receivePosts(subreddit, json));
      }
    }
    
        2
  •  1
  •   markerikson    8 年前

    是的,我相信您的第二个示例相当于基于承诺的代码片段,尽管存在语法错误。

    你只能从 fetch() 调用自身,如果出现错误,则记录并停止。假设没有错误,它会分派操作。是的,所有人 async 函数自动返回承诺。

    错误在于 const json = await response.json() 是块范围的,所以 json 变量在 try {} 封锁。你想申报 let json; try ,以便以后参考。