比赛直到第一次解决,或全部拒绝(反之)

时间:2017-10-13 14:41:46

标签: redux-saga

我正在尝试创建一个在并行中运行多个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 个答案:

答案 0 :(得分:1)

您可以使用bluebird的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;
        }
    }
}