2017-10-13 29 views
1

我試圖創建一個並行運行多個fetch的傳奇,它應該直到第一個fetch解決,或者全部fetch拒絕。我無法想象這個功能。比賽直到第一次解決,或全部拒絕(全部倒過來)

我正在試驗race,但是即使是第一次拒絕,這也正在完成比賽。這是我的傳奇:

const pingOfflineSaga = function* pingOfflineSaga() { 
    while (true) { 
     yield take(PING_OFFLINE); 

     const OFFLINE_SERVERS = ['https://duckduckgo.com/', 'https://www.bing.com/', 'https://www.google.com/']; 


     const responses = yield race(OFFLINE_SERVERS.reduce((acc, server) => { 
      acc[server] = call(fetch200, server); 
      return acc; 
     }, {})); 

     const [ res ] = Object.values(responses); 
     if (res === true) { 
      yield put(update({ isOffline:undefined })); 
      break; 
     } 
    } 
} 

我想盡快解決第一個200狀態響應。 fetch200是這樣的:

async function fetch200(url) { 
    let res; 
    try { 
     res = await fetch(url); 
    } catch(err) { 
     throw new Error(`fetch200 :: Fetch errored with message: ${err.message}`); 
    } 
    if (res.status === 200) { 
     return true; 
    } else { 
     throw new Error('fetch200 :: Fetch did not get 200 status'); 
    } 
} 

all效果逆。

回答

1

你可以使用藍鳥的Promise.any方法

const pingOfflineSaga = function* pingOfflineSaga() { 
    while (true) { 
     yield take(PING_OFFLINE); 
     const OFFLINE_SERVERS = ['https://duckduckgo.com/', 'https://www.bing.com/', 'https://www.google.com/'];  
     const promises = OFFLINE_SERVERS.map(server => fetch(server));    
     result = yield call(Promise.any, promises); 

     if (result) { 
      yield put(update({ isOffline:undefined })); 
      break; 
     } 
    } 
} 
+0

感謝模糊,我一直在尋找一種方式來與僅使用終極版 - 佐賀效果做到這一點。最壞的情況如果我在'fetch200'中找到狀態200並使用'all'的效果,我可以做一個'throw'。但現在'扔'並不壞,它的目標是什麼,「第一次扔」。但我更喜歡不這樣做,因爲這不是最簡單的理由,它的反邏輯哈哈。 – Noitidart