bai3/note

高级-技巧

Opened this issue · 0 comments

bai3 commented

技巧

节流

你可以通过在监听的Saga里调用一个delay函数,针对一系列发起的action进行节流。举个例子,假设用户在文本框输入文字的时候,UI触发了一个INPUT_CHANGED action:

import { throttle } from 'redux-saga/effects'
function* handleInput(input) {
    ...
}
    
function* watchInput() {
    yield throttle(500, 'INPUT_CHANGED', handleInpit)
}

通过使用throttle helper,watchInput不会在500ms启动一个新的handleInput task。这确保Saga在500ms这段时间,最多接受一个INPUT_CHANGED action,并且可以继续处理trailing action。

防抖动

为了对action队列进行防抖动,可以在被fork的任务里放一个内置的delay

import { call, cancel, fork, take, delay } from 'redux-saga/effects'

function* handleInput(input) {
    //500ms防抖动
    yield delay(500)
}

function* watchInput() {
    let task
    while(true) {
        const { input } = yield take('INPUT_CHANGED')
        if(task) {
            yield cancel(task)
        }
        take = yield fork(handleInput, input)
    }
}

在上面的示例中,handleInput在执行之前等待了500ms,如果用户在此期间输入了更多文字,我们将收到更多的INPUT_CHANGED action。并且由于handleInput 仍然会被delay阻塞,所以在执行自己的逻辑之前它会被watchInput取消。

ajax重试

为了重试指定次数的XHR调用,使用一个for循环和一个delay:

import { call, put, take, delay } from 'redux-saga/effects'

function* updateApi(data) {
    for(let i = 0; i < 5; i++){
        try {
            const apiResponse = yield call(apiRequest, {data});
            return apiResponse;
        }catch(err){
            if(i < 4){
                yield delay(2000);
            }
        }
    }
    //重试5次后失败
    throw new Error('API request failed');
}

export default function* updateResource() {
    while (true) {
        const { data } = yield take('UPDATE_STSRT');
        try {
            const apiResponse = yield call(updateApi, data);
            yield put({
                type: 'UPDATE_SUCCESS',
                payload: apiResponse.body
            })
        }catch (error){
            yield put({
                type: 'UPDATE_ERROR',
                error
            })
        }
    }
}

在上面的例子中,apiRequest将重试5次,每次延迟2秒。在5次失败后,将会通过父级saga抛出一个异常。