如何从一个 redux-saga 中的不同 API 获取数据?

How to fetch data from different APIs inside one redux-saga?

我有一个使用 redux-saga 的 React 项目,我需要调用 2 API 来获取我需要的所有数据。

如果我需要获取所有产品,我通常这样做:

function* fetchProducts() {
  const products = yield call(API.getProducts)
  yield put({type: "UPDATE_PRODUCTS", products})
}

现在假设我的 product 对象有一个 brandId 字段,我可以用它从另一个 API 获取 brand 数据。

我想:

  1. 获取所有产品
  2. 循环产品,并为每个产品加载其品牌信息
  3. 更新我的 products 对象以包含品牌信息
  4. 在我的全局状态中保存新的 products 对象

我试过这样的事情:

function* fetchProducts() {
  const products = yield call(API.getProducts)
  const productsWithBrand = products.map((product) => {
    const brand = yield call(API.getBrand, product.brandId)
    return {
      ...product,
      brandData: brand,
    }
  })
  yield put({type: "UPDATE_PRODUCTS", productsWithBrand})
}

这给了我错误:

Parsing error: Unexpected reserved word 'yield'

阅读 后,我明白了为什么会发生错误,但我无法找出正确的语法来实现我想要的。

是否有实现我需要的通用模式?

在传递给 map 的函数中 yield 在语法上是无效的,因为 map 不知道生成器。一种常见的模式是选择 for...of 循环或常规 for 循环来为集合中的每个项目执行异步操作。 https://medium.com/free-code-camp/redux-saga-common-patterns-48437892e11c

function* fetchProducts() {
    const products = yield call(API.getProducts);
    const productsWithBrands = [];
    for (let product of products) {
        const productWithBrand = yield call(API.getBrand, product.brandId);
    
        const { error } = yield race({
            success: take(SUCCESS),
            error: take(FAILURE),
        });
        
        if(error) {
            // Implement specific error handling
            // eg: break;
        }
        productsWithBrands.push(productWithBrand);          
    }
   yield put({type: "UPDATE_PRODUCTS", productsWithBrands });
}