我需要从 r 运行 并行的任务中取消 redux saga 中的特定任务。使用下面的代码,所有并行任务都被取消
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
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)
}
}
有多种方法可以做到这一点,例如,您可以使用具有 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_PROGRESS
和 ON_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。
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)
}
}
有多种方法可以做到这一点,例如,您可以使用具有 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_PROGRESS
和 ON_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。