第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機(jī)立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

createAsyncThunk:中止先前的請求

createAsyncThunk:中止先前的請求

慕勒3428872 2023-07-06 17:36:25
我用來createAsyncThunk向某些 API 發(fā)出異步請求。在任何給定時刻只能有一個請求處于活動狀態(tài)。AbortSignal據(jù)我所知,如果我從上次調(diào)用中返回了 Promise,則可以使用提供的方法中止該請求。問題是,thunk 本身能否以某種方式“自主”中止先前的請求?我正在考慮兩種選擇:將最后一個 AbortSignal 保持在狀態(tài)中。似乎是錯誤的,因?yàn)闋顟B(tài)應(yīng)該是可序列化的。將最后一個 Promise 及其 AbortSignal 保留在全局變量中。似乎也是錯誤的,因?yàn)?,你知道,全局變量。有任何想法嗎?謝謝。
查看完整描述

2 回答

?
慕森卡

TA貢獻(xiàn)1806條經(jīng)驗(yàn) 獲得超8個贊

我不知道您的特定 api 是如何工作的,但下面是一個工作示例,說明如何將中止邏輯放入操作和減速器中,當(dāng)進(jìn)行新的提取時,它將中止任何先前活動的假提取:


import * as React from 'react';

import ReactDOM from 'react-dom';

import {

  createStore,

  applyMiddleware,

  compose,

} from 'redux';

import {

  Provider,

  useDispatch,

  useSelector,

} from 'react-redux';

import {

  createAsyncThunk,

  createSlice,

} from '@reduxjs/toolkit';


const initialState = {

  entities: [],

};

// constant value to reject with if aborted

const ABORT = 'ABORT';

// fake signal constructor

function Signal() {

  this.listener = () => undefined;

  this.abort = function () {

    this.listener();

  };

}

const fakeFetch = (signal, result, time) =>

  new Promise((resolve, reject) => {

    const timer = setTimeout(() => resolve(result), time);

    signal.listener = () => {

      clearTimeout(timer);

      reject(ABORT);

    };

  });

// will abort previous active request if there is one

const latest = (fn) => {

  let previous = false;

  return (signal, result, time) => {

    if (previous) {

      previous.abort();

    }

    previous = signal;

    return fn(signal, result, time).finally(() => {

      //reset previous

      previous = false;

    });

  };

};

// fake fetch that will abort previous active is there is one

const latestFakeFetch = latest(fakeFetch);


const fetchUserById = createAsyncThunk(

  'users/fetchByIdStatus',

  async ({ id, time }) => {

    const response = await latestFakeFetch(

      new Signal(),

      id,

      time

    );

    return response;

  }

);

const usersSlice = createSlice({

  name: 'users',

  initialState: { entities: [], loading: 'idle' },

  reducers: {},

  extraReducers: {

    [fetchUserById.fulfilled]: (state, action) => {

      state.entities.push(action.payload);

    },

    [fetchUserById.rejected]: (state, action) => {

      if (action?.error?.message === ABORT) {

        //do nothing

      }

    },

  },

});


const reducer = usersSlice.reducer;

//creating store with redux dev tools

const composeEnhancers =

  window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;

const store = createStore(

  reducer,

  initialState,

  composeEnhancers(

    applyMiddleware(

      ({ dispatch, getState }) => (next) => (action) =>

        typeof action === 'function'

          ? action(dispatch, getState)

          : next(action)

    )

  )

);

const App = () => {

  const dispatch = useDispatch();

  React.useEffect(() => {

    //this will be aborted as soon as the next request is made

    dispatch(

      fetchUserById({ id: 'will abort', time: 200 })

    );

    dispatch(fetchUserById({ id: 'ok', time: 100 }));

  }, [dispatch]);

  return 'hello';

};


ReactDOM.render(

  <Provider store={store}>

    <App />

  </Provider>,

  document.getElementById('root')

);

如果您只需要解決一個承諾(如果它是最新請求的承諾),而無需中止或取消正在進(jìn)行的承諾(如果不是最新的則忽略解決),那么您可以執(zhí)行以下操作:


const REPLACED_BY_NEWER = 'REPLACED_BY_NEWER';

const resolveLatest = (fn) => {

  const shared = {};

  return (...args) => {

    //set shared.current to a unique object reference

    const current = {};

    shared.current = current;

    fn(...args).then((resolve) => {

      //see if object reference has changed

      //  if so it was replaced by a newer one

      if (shared.current !== current) {

        return Promise.reject(REPLACED_BY_NEWER);

      }

      return resolve;

    });

  };

};

這個答案演示了如何使用它



查看完整回答
反對 回復(fù) 2023-07-06
?
天涯盡頭無女友

TA貢獻(xiàn)1831條經(jīng)驗(yàn) 獲得超9個贊

我能夠?qū)⑵浞旁谝黄?,但它非常?fù)雜。


以下函數(shù)創(chuàng)建執(zhí)行實(shí)際工作的“內(nèi)部”異步 thunk,以及委托給內(nèi)部異步 thunk 并中止之前的調(diào)度(如果有)的“外部”異步 thunk。


內(nèi)部 thunk 的有效負(fù)載創(chuàng)建者也被包裝為:1)等待有效負(fù)載創(chuàng)建者的先前調(diào)用完成,2)如果操作在等待期間中止,則跳過調(diào)用真正的有效負(fù)載創(chuàng)建者(以及 API 調(diào)用)。


import { createAsyncThunk, AsyncThunk, AsyncThunkPayloadCreator, unwrapResult } from '@reduxjs/toolkit';


export function createNonConcurrentAsyncThunk<Returned, ThunkArg>(

  typePrefix: string,

  payloadCreator: AsyncThunkPayloadCreator<Returned, ThunkArg>,

  options?: Parameters<typeof createAsyncThunk>[2]

): AsyncThunk<Returned, ThunkArg, unknown> {

  let pending: {

    payloadPromise?: Promise<unknown>;

    actionAbort?: () => void;

  } = {};


  const wrappedPayloadCreator: AsyncThunkPayloadCreator<Returned, ThunkArg> = (arg, thunkAPI) => {

    const run = () => {

      if (thunkAPI.signal.aborted) {

        return thunkAPI.rejectWithValue({name: 'AbortError', message: 'Aborted'});

      }

      const promise = Promise.resolve(payloadCreator(arg, thunkAPI)).finally(() => {

        if (pending.payloadPromise === promise) {

          pending.payloadPromise = null;

        }

      });

      return pending.payloadPromise = promise;

    }


    if (pending.payloadPromise) {

      return pending.payloadPromise = pending.payloadPromise.then(run, run); // don't use finally(), replace result

    } else {

      return run();

    }

  };


  const internalThunk = createAsyncThunk(typePrefix + '-protected', wrappedPayloadCreator);


  return createAsyncThunk<Returned, ThunkArg>(

    typePrefix,

    async (arg, thunkAPI) => {

      if (pending.actionAbort) {

        pending.actionAbort();

      }

      const internalPromise = thunkAPI.dispatch(internalThunk(arg));

      const abort = internalPromise.abort;

      pending.actionAbort = abort;

      return internalPromise

        .then(unwrapResult)

        .finally(() => {

          if (pending.actionAbort === abort) {

            pending.actionAbort = null;

          }

        });

    },

    options

  );

}



查看完整回答
反對 回復(fù) 2023-07-06
  • 2 回答
  • 0 關(guān)注
  • 214 瀏覽
慕課專欄
更多

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號