如何动态调度和等待承诺

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>