React-Saga-如何使嵌套生成器工作

时间:2019-09-22 13:40:34

标签: redux react-redux redux-saga

我从旧的redux saga升级到了最新版本,并且以下版本停止了工作。

function* loadAlbumPhoto({ entity }, entityId) {
      try {
        const { accessToken: at } = yield select(state => state.user.info);

        let {
          data: { data: albums }
        } = yield call(API.loadAlbumByEntityId, { entityName: entity, entityId, type: PHOTO });

        if (!albums.length) {
          const options = {
            entityId,
            entityName: entity,
            title:      PHOTO,
            type:       PHOTO
          };
          yield call(API.createAlbum, options);
          ({ data: { data: albums } } = yield call(API.loadAlbumByEntityId, { entityName: entity, entityId, type: PHOTO }));
        }

        const [album] = albums;

        const { data: { data: photos } } = yield call(API.loadPhotosByAlbumId, album.id);
        return yield photos.map(function* (photo) {
          const src = yield getPhotoUrl(photo.uploadData.path, at);

          return {
            src,
            uploadId: photo.uploadId,
            photoId:  photo.id
          };
        });
      } catch (err) {

        console.log(err);

        return [];
      }
    }


function* getPhotoUrl(path, at) {
  try {
    const userPhoto = yield API.userPhoto(path, at);
    return userPhoto;
  } catch (err) {
    /* eslint-disable no-console */
    console.log(err);
    /* eslint-enable no-console */
  }
  return "";
}

如您所见,我正在尝试从loadAlbumPhoto返回数组,但是我的问题是我需要调用getPhotoUrl函数,这也是一个生成器函数。

问题在于loadAlbumPhoto的结果是生成器数组而不是值数组。自从我升级到redux和redux saga的最新版本以来,就发生了这种情况。

已经尝试使用yield*,但是没有用,或者我不知道如何使用它。 yield*

enter image description here

1 个答案:

答案 0 :(得分:1)

我将对匿名生成器进行一些重构,然后将您的yield转换为使用allhttps://redux-saga.js.org/docs/api/#alleffects---parallel-effects

function* getPhotoDetails(photo) {
  const src = yield getPhotoUrl(photo.uploadData.path, at);
  return {
    src,
    uploadId: photo.uploadId,
    photoId:  photo.id
  };
}

function* loadAlbumPhoto({ entity }, entityId) {
    // similar up to yield photos.map...
    return yield all(photos.map(photo => call(getPhotoDetails, photo)));
    // similar after
}