如何动态调度和等待承诺
How to dynamically dispatch and wait for promises
如何通过 redux 分配动态确定的次数?
我有一些用户能够创建项目列表,并且可以根据需要创建任意数量的项目。当他们导航到项目页面时,他们可以选择要将其添加到的列表。
这意味着我可能不得不派遣将一项或更多项添加到一个列表中。
只有当所有发送到 'add an item' 到列表 return 的承诺时,我才想发送接收更新列表的操作。
如果我遍历一个数组并传入一个参数来分派,有没有办法在继续下一个之前等待承诺step/array-index?
例如,我需要多次调用类似的东西,但多少次将由用户决定,应该只
export const addToList = (user_id, list_id, stock_ticker) => dispatch => {
return StockApiutil.addToList(user_id, list_id, stock_ticker)
.then(lists => dispatch(receiveLists(lists)))
};
export const addToAllLists = (user_id, list_ids, stock_ticker) => dispatch => {
dispatch(startListLoading());
list_ids.map( list_id =>
addToList(user_id, list_id, stock_ticker)
)
.then(dispatch(stopListLoading()))
}
这不起作用,因为它不是 return 承诺,如果我使用 promise.all,我将不会创建对应于列表最终状态的数组。
您可以执行以下操作:
export const addToList = (
user_id,
list_id,
stock_ticker
) => (dispatch) => {
//you are returning a promise here, that is good
return StockApiutil.addToList(
user_id,
list_id,
stock_ticker
).then((lists) => dispatch(receiveLists(lists)));
};
export const addToAllLists = (
user_id,
list_ids,
stock_ticker
) => (dispatch) => {
dispatch(startListLoading());
//return a single promise using Promise.all
return Promise.all(
list_ids.map((list_id) =>
//also add (dispatch) so you actually call the thunk
addToList(user_id, list_id, stock_ticker)(dispatch)
)
).then(()=>dispatch(stopListLoading()));
};
最后一行有语法错误,应该是.then(()=>dispatch(stopListLoading()));
看你的参数名我看你不习惯写JS代码,如果你运行 它,下面是一个工作示例:
const { Provider, useDispatch } = ReactRedux;
const { createStore, applyMiddleware, compose } = Redux;
//actions
const later = (...args) =>
new Promise((r) => setTimeout(() => r(args), 100));
const StockApiutil = {
addToList: (a, b, c) => later(a, b, c),
};
const receiveLists = (list) => ({
type: 'recieveList',
payload: list,
});
const startListLoading = (payload) => ({
type: 'startListLoading',
payload,
});
const stopListLoading = (payload) => ({
type: 'stopListLoading',
payload,
});
const addToList = (user_id, list_id, stock_ticker) => (
dispatch
) => {
return StockApiutil.addToList(
user_id,
list_id,
stock_ticker
).then((lists) => dispatch(receiveLists(lists)));
};
const addToAllLists = (user_id, list_ids, stock_ticker) => (
dispatch
) => {
dispatch(startListLoading());
//return a single promise using Promise.all
return Promise.all(
list_ids.map((list_id) =>
//also add (dispatch) so you actually call the thunk
addToList(user_id, list_id, stock_ticker)(dispatch)
)
).then(() => dispatch(stopListLoading()));
};
const reducer = (state, { type, payload }) => {
console.log('in reducer:', type, payload);
return state;
};
//creating store with redux dev tools
const composeEnhancers =
window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const store = createStore(
reducer,
{},
composeEnhancers(
applyMiddleware(
({ dispatch, getState }) => (next) => (action) =>
//simple thunk implementation
typeof action === 'function'
? action(dispatch, getState)
: next(action)
)
)
);
const App = () => {
const dispatch = useDispatch();
React.useEffect(
() =>
dispatch(
addToAllLists(
'user id',
[1, 2, 3, 4, 5],
'stock ticker'
)
),
[dispatch]
);
return 'check the console';
};
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/redux/4.0.5/redux.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-redux/7.2.0/react-redux.min.js"></script>
<div id="root"></div>
如何通过 redux 分配动态确定的次数?
我有一些用户能够创建项目列表,并且可以根据需要创建任意数量的项目。当他们导航到项目页面时,他们可以选择要将其添加到的列表。
这意味着我可能不得不派遣将一项或更多项添加到一个列表中。
只有当所有发送到 'add an item' 到列表 return 的承诺时,我才想发送接收更新列表的操作。
如果我遍历一个数组并传入一个参数来分派,有没有办法在继续下一个之前等待承诺step/array-index?
例如,我需要多次调用类似的东西,但多少次将由用户决定,应该只
export const addToList = (user_id, list_id, stock_ticker) => dispatch => {
return StockApiutil.addToList(user_id, list_id, stock_ticker)
.then(lists => dispatch(receiveLists(lists)))
};
export const addToAllLists = (user_id, list_ids, stock_ticker) => dispatch => {
dispatch(startListLoading());
list_ids.map( list_id =>
addToList(user_id, list_id, stock_ticker)
)
.then(dispatch(stopListLoading()))
}
这不起作用,因为它不是 return 承诺,如果我使用 promise.all,我将不会创建对应于列表最终状态的数组。
您可以执行以下操作:
export const addToList = (
user_id,
list_id,
stock_ticker
) => (dispatch) => {
//you are returning a promise here, that is good
return StockApiutil.addToList(
user_id,
list_id,
stock_ticker
).then((lists) => dispatch(receiveLists(lists)));
};
export const addToAllLists = (
user_id,
list_ids,
stock_ticker
) => (dispatch) => {
dispatch(startListLoading());
//return a single promise using Promise.all
return Promise.all(
list_ids.map((list_id) =>
//also add (dispatch) so you actually call the thunk
addToList(user_id, list_id, stock_ticker)(dispatch)
)
).then(()=>dispatch(stopListLoading()));
};
最后一行有语法错误,应该是.then(()=>dispatch(stopListLoading()));
看你的参数名我看你不习惯写JS代码,如果你运行 它,下面是一个工作示例:
const { Provider, useDispatch } = ReactRedux;
const { createStore, applyMiddleware, compose } = Redux;
//actions
const later = (...args) =>
new Promise((r) => setTimeout(() => r(args), 100));
const StockApiutil = {
addToList: (a, b, c) => later(a, b, c),
};
const receiveLists = (list) => ({
type: 'recieveList',
payload: list,
});
const startListLoading = (payload) => ({
type: 'startListLoading',
payload,
});
const stopListLoading = (payload) => ({
type: 'stopListLoading',
payload,
});
const addToList = (user_id, list_id, stock_ticker) => (
dispatch
) => {
return StockApiutil.addToList(
user_id,
list_id,
stock_ticker
).then((lists) => dispatch(receiveLists(lists)));
};
const addToAllLists = (user_id, list_ids, stock_ticker) => (
dispatch
) => {
dispatch(startListLoading());
//return a single promise using Promise.all
return Promise.all(
list_ids.map((list_id) =>
//also add (dispatch) so you actually call the thunk
addToList(user_id, list_id, stock_ticker)(dispatch)
)
).then(() => dispatch(stopListLoading()));
};
const reducer = (state, { type, payload }) => {
console.log('in reducer:', type, payload);
return state;
};
//creating store with redux dev tools
const composeEnhancers =
window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const store = createStore(
reducer,
{},
composeEnhancers(
applyMiddleware(
({ dispatch, getState }) => (next) => (action) =>
//simple thunk implementation
typeof action === 'function'
? action(dispatch, getState)
: next(action)
)
)
);
const App = () => {
const dispatch = useDispatch();
React.useEffect(
() =>
dispatch(
addToAllLists(
'user id',
[1, 2, 3, 4, 5],
'stock ticker'
)
),
[dispatch]
);
return 'check the console';
};
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/redux/4.0.5/redux.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-redux/7.2.0/react-redux.min.js"></script>
<div id="root"></div>