我正在尝试了解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 async / await语法...行为完全一样吗?
我首先想到了这一点:
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));
}
}
但是在发生错误的情况下,我不确定行为是否与没有异步/等待的示例相同。我不确定是否需要将return
放在catch
块中。该示例返回了一个承诺,我不确定我的代码是否仍会发生。
在搜索它时,我仅发现this question但没有响应,并且发现了一个使用生成器/ yield语法的redux-saga组件。我应该在异步/等待时使用redux-saga而不是redux-thunk吗?
答案 0 :(得分:1)
是的,我相信您的第二个示例等效于基于promise的代码段,尽管存在语法错误。
您仅从fetch()
调用本身中捕获错误,并且在出现错误的情况下,将其记录并停止在那里。假设没有错误,则调度该动作。是的,所有async
函数都会自动返回一个Promise。
错误是const json = await response.json()
是块作用域的,因此json
变量将不能在try {}
块之外访问。您希望在let json;
之前声明try
,以便以后可以引用它。
答案 1 :(得分:1)
我的感觉是原始代码实际上应该是
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解析的替代方法(并且无条件地进行调度,可能带有未定义的{{1} }值。
这种分支is hard to achieve with try
/catch
when using async
/await
,所以我只保留json
语法。如果您想重写它,则可以进行第二次尝试(相当于我更正后的then
语法),但是您需要在then
块之外声明json
(或使用{ {1}}代替try
):
var