【问题标题】:I need to cancel a particular task in redux saga from the tasks which r running parallely. with the code below all of the parallel tasks are cancelled我需要从并行运行的任务中取消 redux saga 中的特定任务。使用下面的代码,所有并行任务都被取消
【发布时间】:2022-01-20 20:46:24
【问题描述】:
function* imageUploadfunctionCall(payload) {
  for (let image of payload.payload) {
    const {response, error} = yield call(imageUploadRequest(image))
    if (response) {
      yield put({type: ON_UPLOAD_SUCCESS, payload: image})
    } else if (error) {
      console.log('error', error)
    }
  }
}

export function* watchImageUpload() {
  while (true) {
    let workerTask = yield takeEvery(
      ON_UPLOAD_PROGRESS,
      imageUploadfunctionCall
    )
    yield take(ON_CANCEL_BATCH_UPLOAD)
    yield cancel(workerTask)
  }
}

【问题讨论】:

    标签: reactjs react-redux redux-saga


    【解决方案1】:

    有多种方法可以做到这一点,例如,您可以使用具有race 效果的中间传奇:

    function* imageUploadfunctionCall(payload) {
      for (let image of payload.payload) {
        const {response, error} = yield call(imageUploadRequest(image))
        if (response) {
          yield put({type: ON_UPLOAD_SUCCESS, payload: image})
        } else if (error) {
          console.log('error', error)
        }
      }
    }
    
    function* imageUploadSaga(payload) {
      yield race([
        call(imageUploadfunctionCall, payload),
        take(a => a.type === ON_CANCEL_BATCH_UPLOAD && a.id === payload.id),
      ])
    }
    
    export function* watchImageUpload() {
      yield takeEvery(ON_UPLOAD_PROGRESS, imageUploadSaga)
    }
    

    上面的代码假定您为ON_UPLOAD_PROGRESSON_CANCEL_BATCH_UPLOAD 操作都发送了id 属性,以便您可以确定要取消哪个操作。

    顺便说一句,在上传传奇中你有:

    yield call(imageUploadRequest(image))
    

    应该是这样的

    yield call(imageUploadRequest, image)
    

    (除非imageUploadRequest 是函数工厂)。


    对于更复杂的情况,您可以保存任务和 ID 的地图。

    export function* watchImageUpload() {
      const taskMap = {}
    
      yield takeEvery(ON_CANCEL_BATCH_UPLOAD, function* (action) {
        if (!taskMap[action.payload]) return
        yield cancel(taskMap[action.payload])
        delete taskMap[action.payload]
      })
    
      while (true) {
        let payload = yield take(ON_UPLOAD_PROGRESS, imageUploadSaga)
        const workerTask = yield fork(imageUploadfunctionCall, payload)
        taskMap[payload.id] = workerTask
      }
    }
    

    同样,您在这两个操作中都需要一些 id。

    【讨论】:

    • 嘿,非常感谢马丁。
    猜你喜欢
    • 2021-12-11
    • 2019-07-10
    • 2018-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多