最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to join a collection of Promises asyncrounously in a Saga? - Stack Overflow

programmeradmin2浏览0评论

Within a redux saga I am sending a half dozen fetch requests to different systems. I want to wait until all those requests return, then do some final processing on the results.

To this end I have an array of promises, representing each query. I could call Promise.all() on the array, but this would cause the saga to hang, and thus all events to hang, until the promises return.

I tried creating an async promise that called promise.all, then using the redux-effects Call on that promise, but this also hung.

How can I keep the async nature of my saga while waiting for the promises to return?

Within a redux saga I am sending a half dozen fetch requests to different systems. I want to wait until all those requests return, then do some final processing on the results.

To this end I have an array of promises, representing each query. I could call Promise.all() on the array, but this would cause the saga to hang, and thus all events to hang, until the promises return.

I tried creating an async promise that called promise.all, then using the redux-effects Call on that promise, but this also hung.

How can I keep the async nature of my saga while waiting for the promises to return?

Share Improve this question edited Jun 5, 2019 at 7:00 Bulat 7167 silver badges15 bronze badges asked Aug 15, 2018 at 13:17 dsollendsollen 6,4596 gold badges47 silver badges94 bronze badges 3
  • I'm not sure I'm following the question. If you need all responses back to plete the final processing, then you must wait for the responses to e back. There's no getting around that. While the saga is waiting for the responses to e back, the rest of your app will continue to receive events. The saga will hang or pause execution until all responses e back, but it won't block the js event loop. This seems obvious, so I feel like I must be missing the question. – tpdietz Commented Aug 15, 2018 at 16:41
  • @tpdietz It is blocking the JS event loop for me, and that is what I would expect as behavior as well. Since doing something like calling promise.all would casue a blocking wait the saga's event won't plete (or yield). It continues executing, even though it's only executing a sleep mand, preventing other event's from running. Specifically I see actions dispatched to change sorting on my table not execute until the saga pletes when I use that approach. – dsollen Commented Aug 15, 2018 at 16:45
  • This seems odd for sure. How are you invoking the saga? – tpdietz Commented Aug 15, 2018 at 16:53
Add a ment  | 

2 Answers 2

Reset to default 14

To run all request in parallel you should use the all effect from redux-saga. Its analogous to the Promise.all method you referenced already.

Example:

import { fetchCustomers, fetchProducts } from './path/to/api'
import { all, call } from `redux-saga/effects`

function* mySaga() {
  const { customers, products } = yield all({
    customers: call(fetchCustomers),
    products: call(fetchProducts)
  });
  // do something with results
}

This is the most straight forward way to run asynchronous operations in parallel and wait for all processes to plete. This approach will not block the javascript event loop. It will only block the remainder of the generator function from running. Other actions in other sagas, and other events (such as clicks), will still be received by your application while the requests are in flight.

Please refer to the official docs for more information.

You can do something like this

*getProductsSaga() {
    while (true) {
      yield take(types.GET_PRODUCTS_REQUEST);
      try {
        const result1 = yield call(() => getProducts1Promise());
        const result2 = yield call(() => getProducts2Promise());
        const result3 = yield call(() => getProducts3Promise());
        const result4 = yield call(() => getProducts4Promise());
        yield put({
          type: types.GET_PRODUCTS_SUCCESS,
          payload: [result1, result2, result3, result4] // process/bine results depending on how you want
        });
      } catch (error) {
        yield put({
          type: types.GET_PRODUCTS_FAILURE,
          payload: error
        });
      }
    }
  }
发布评论

评论列表(0)

  1. 暂无评论