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

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

開玩笑地忽略被拒絕的“一勞永逸”承諾

開玩笑地忽略被拒絕的“一勞永逸”承諾

尚方寶劍之說 2023-10-14 11:12:16
我的商店的processAction()函數(shù)以“即發(fā)即忘”的方式調(diào)用私有異步函數(shù),然后進行提取。 processAction()它本身不處理任何錯誤處理,并且在瀏覽器中,如果獲取失敗,外部庫將處理所有未捕獲的承諾拒絕。因此,如果我模擬我的獲取以拒絕,則私有函數(shù)(我正在測試的效果)將拒絕。由于我沒有對異步函數(shù)調(diào)用創(chuàng)建的承諾的引用,因此我無法在測試中捕獲拒絕,但測試失敗,因為存在未處理的拒絕。我怎樣才能告訴 jest 接受這種調(diào)用私有函數(shù)本身的短時間,而不是僅僅觸發(fā)調(diào)用它的操作?動作.tsconst actions = {  doTheThing() {    dispatch({ type: 'DO_THE_THING' });  },};export default actions;商店.tsimport fetch from './fetch';class Store {  isFetching = false;  // ...  processAction({ type, payload }: { type: string, payload: any }) {    switch (type) {      case 'DO_THE_THING':        this.fetchTheThing();        break;    }  }  private async fetchTheThing() {    try {      this.isFetching = true;      const result = await fetch(myUrl);      // ...    } finally {      this.isFetching = false;    }  }}export default new Store();__mocks__/fetch.tslet val: any;interface fetch {  __setVal(value: any): void;}export default async function fetch() {  return val;}fetch.__setVal = function(value: any) {  val = value;};商店.test.tsimport actions from './actions';import store from './store';const fetch = (require('./fetch') as import('./__mocks__/fetch')).default;jest.mock('./fetch');test('it sets/unsets isFetching on failure', async () => {  let rej: () => void;  fetch.__setVal(new Promise((_, reject) => rej = reject));  expect(store.isFetching).toBe(false);  Actions.doTheThing();  await Promise.sleep(); // helper function  expect(store.isFetching).toBe(true);  rej(); // <---- test fails here  await Promise.sleep();  expect(store.isFetching).toBe(false);});
查看完整描述

2 回答

?
ABOUTYOU

TA貢獻1812條經(jīng)驗 獲得超5個贊

我的函數(shù)以“即發(fā)即忘”的方式調(diào)用私有異步函數(shù),并且不添加任何錯誤處理。

不要那樣做。

外部庫處理所有未捕獲的承諾拒絕。在生產(chǎn)中,我希望 shell 來處理它,所以我不想在函數(shù)本身中處理它。

不要依賴這個外部庫。

您應(yīng)該在函數(shù)中使用自己的全局錯誤處理函數(shù)。

在生產(chǎn)中,讓該錯誤處理函數(shù)簡單地重新拋出異常,以便環(huán)境能夠捕獲該異常,或者更好的是,如果可能的話,直接調(diào)用 shell 錯誤處理函數(shù)。

在測試中,您可以模擬自己的全局處理程序,并斷言它是使用預(yù)期參數(shù)調(diào)用的。


查看完整回答
反對 回復(fù) 2023-10-14
?
qq_花開花謝_0

TA貢獻1835條經(jīng)驗 獲得超7個贊

processAction是同步的并且不知道 Promise,這會導(dǎo)致懸空的 Promise。懸空承諾永遠不應(yīng)該拒絕,因為這會導(dǎo)致未經(jīng)處理的拒絕,這是一種例外。根據(jù)環(huán)境的不同,這可能會導(dǎo)致應(yīng)用程序崩潰。即使異常是全局處理的,這也不應(yīng)該成為不處理預(yù)期錯誤的理由。


正確的方法是在fetchTheThing拒絕發(fā)生的地方明確抑制拒絕:


  private async fetchTheThing() {

    try {

      ... 

    } catch {} finally {

      this.isFetching = false;

    }

  }

或者在這種情況下,它更像processAction是導(dǎo)致懸而未決的承諾:


this.fetchTheThing().catch(() => {});

否則將調(diào)度未處理的拒絕事件。


如果沒有的話,可以通過監(jiān)聽事件來測試:


  ...

  let onRej = jest.fn();

  process.once('unhandledRejection', onRej);

  rej();

  await Promise.sleep();

  expect(onRej).toBeCalled();

  expect(store.isFetching).toBe(false);

如果已經(jīng)有另一個監(jiān)聽器,這將無法按預(yù)期工作unhandledRejection,這在良好的 Jest 設(shè)置中是可以預(yù)期的。如果是這種情況,唯一不會影響其他測試的解決方法是在測試之前重置它們并在測試之后重新添加:


let listeners;


beforeEach(() => {

  listeners = process.rawListeners('unhandledRejection');

  process.removeAllListeners('unhandledRejection');

});


afterEach(() => {

  (typeof listeners === 'function' ? [listeners] : listeners).forEach(listener => {

    process.on('unhandledRejection', listener);

  });

})

不建議這樣做,使用時應(yīng)自行承擔風險,因為這表明錯誤處理存在更深層次的問題,而在正確設(shè)計的 JavaScript 應(yīng)用程序中通常不可接受。


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

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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