我正在尝试将调度与 redux thunk 链接起来
function simple_action(){
return {type: "SIMPLE_ACTION"}
}
export function async_action(){
return function(dispatch, getState){
return dispatch(simple_action).then(()=>{...});
}
}
如何让派单从商店返回承诺?
更具体地说:
我可能只是不明白这里的东西,但是在所有带有redux-thunk
的例子中,它们调用了一个单独的异步事件(如fetch
),这显然会返回一个Promise
。
我特别要寻找的是当我向商店发送操作时:如何确保商店在上述函数中发生任何其他事情之前action_creator()
完全处理了该操作。
理想情况下,我希望商店返回某种承诺,但我不明白这是如何或在哪里发生的?
这里有一个关于如何调度和链接异步操作的示例。 https://github.com/gaearon/redux-thunk
thunk 中间件知道如何将 thunk 异步操作转换为操作,所以你只需要让你的 simple_action() 成为一个 thunk,thunk 中间件就会为你完成这项工作,如果中间件看到一个正常的动作,他会把这个动作作为正常动作调度,但如果它是一个异步函数,它会把你的异步动作变成正常的动作。
所以你的simple_action需要是一个thunk(thunk是一个返回函数的函数。例如,像这样:
function makeASandwichWithSecretSauce(forPerson) {
return function (dispatch) {
return fetchSecretSauce().then(
sauce => dispatch(makeASandwich(forPerson, sauce)),
error => dispatch(apologize('The Sandwich Shop', forPerson, error))
);
};
}
使用 makeASandwichWithSecretSauce 函数时,您可以使用调度函数
store.dispatch(
makeASandwichWithSecretSauce('Me')
);
甚至
// It even takes care to return the thunk’s return value
// from the dispatch, so I can chain Promises as long as I return them.
store.dispatch(
makeASandwichWithSecretSauce('My wife')
).then(() => {
console.log('Done!');
});
下面是一个完整的示例,介绍如何编写操作创建者来调度来自其他操作创建者的操作和异步操作,并使用 Promise 构建控制流。
function makeSandwichesForEverybody() {
return function (dispatch, getState) {
if (!getState().sandwiches.isShopOpen) {
// You don’t have to return Promises, but it’s a handy convention
// so the caller can always call .then() on async dispatch result.
return Promise.resolve();
}
//Do this action before starting the next one below
dispatch(simple_action());
// We can dispatch both plain object actions and other thunks,
// which lets us compose the asynchronous actions in a single flow.
return dispatch(
makeASandwichWithSecretSauce('My Grandma')
).then(() =>
Promise.all([
dispatch(makeASandwichWithSecretSauce('Me')),
dispatch(makeASandwichWithSecretSauce('My wife'))
])
).then(() =>
dispatch(makeASandwichWithSecretSauce('Our kids'))
).then(() =>
dispatch(getState().myMoney > 42 ?
withdrawMoney(42) :
apologize('Me', 'The Sandwich Shop')
)
);
};
}
//apologize and withdrawMoney are simple action like this for example
return {
type: "END_SUCESS"
}
//用法
store.dispatch(
makeSandwichesForEverybody()
).then(() =>
console.log("Done !");
);
要创建自己的承诺,您可以使用像蓝鸟这样的库。
//编辑:为了确保存储在函数 action_creator() 中发生任何其他操作之前已完全处理该操作,您可以在 action_creator() 之前调度此simple_action;我将此注释添加到代码//Do this action before starting the next one below
最近一直在使用的模式:
export const someThenableThunk = someData => (dispatch, getState) => Promise.resolve().then(() => {
const { someReducer } = getState();
return dispatch({
type: actionTypes.SOME_ACTION_TYPE,
someData,
});
});
当您dispatch(someThenableThunk('hello-world'))
时,它将返回一个 Promise
对象,您可以将进一步的操作链接到该对象。
dispatch
将返回它调用的任何操作/函数返回;因此,如果要链接某些活动(根据您的示例),您的操作需要返回一个Promise
。
正如@Aaleks提到的,如果您的操作是thunk
则可以创建一个返回Promise
的场景,然后您可以按照您提到的进行操作。
顺便说一句,我认为命名您的thunk
action_creator
有点误导,因为simple_action
实际上是 Redux 用语中的动作创建者 - 已相应地进行了编辑:)
异步操作以及如何在使用redux
和thunk
时从组件调用操作
没有承诺
action.js
export function shareForm(id) {
return function (dispatch) {
dispatch({
type: 'SHARE_FORM',
payload: source.shareForm(id)
})
}
}
SomeComponent.js
dispatch(shareForm(id))
<小时 />有希望
action.js
export function shareForm(id, dispatch) {
return new Promise((resolve, reject) => {
dispatch({
type: 'SHARE_FORM',
payload: source.shareForm(id)
})
.then(res => resolve(res))
.catch(err => reject(err))
})
}
SomeComponent.js
shareForm(id, dispatch)
.then(res => console.log('log on success', res))
.catch(err => console.log('log on failure', err))
PS:如果您需要更多解释,请在评论中告诉我
您需要做的是创建返回 Promise 的中继操作。调度函数返回您作为参数添加到其调用的内容。例如,如果您希望调度返回承诺,则必须将承诺作为参数添加到调用中。
function simple_action() {
return { type: 'SIMPLE_ACTION' };
}
export function async_action(dispatch, getState) {
return function () {
return Promise.resolve(dispatch(simple_action()));
}
}
const boundAction = async_action(dispatch, getState);
boundAction().then(() => {});