首页 > 解决方案 > Promise Race 中的 setTimeout 立即捕获

问题描述

我有 2 个 promise, afetch和 a setTimeout, fetch 等待 5 秒, setTimeout 等待 4 秒。

我不知道为什么,但 setTimeout 立即开火!

myService( args )
    .then( result => {
        console.log(result);
    })  
    .catch( timeoutError => {  // <-----------------  FIRE IMMEDIATELY
        console.error(timeoutError);
    })
;


function myService( args ){
    return Promise.race([
        fetch("http://localhost/wait-ten-seconds"),
        new Promise( (_, timeexpired) => {
            return setTimeout( function() {
                console.log("timeout");
                timeexpired({msg: "call timeout", code: 100, data: null});
            }
            , 4000)
        })
    ]);
}

标签: javascripttimerpromisesettimeoutes6-promise

解决方案


我以这种方式解决它:
我创建了一个模拟超时的函数

let activeTimer = null;
let checkTimer = (startTimer, timeExpired) => {
    activeTimer = setTimeout(() => {
        if( (new Date()).getTime() - startTimer < TIMEOUT_DURATION_MS ) checkTimer(startTimer, timeExpired);
        else timeExpired( errorMessage.TIMEOUT_EXPIRED );
    }, 1000);
};

Promise.race([
    new Promise( (httpResponse, httpError) => {
        return fetch(url)
            .then(response => {
                clearTimeout( activeTimer );
                activeTimer = null;
                httpResponse( response );
            })
            .catch( error => {
                httpError( error );
            })
        })
        ,
        new Promise( (_, timeExpired) => {
            checkTimer((new Date()).getTime(), timeExpired);
        })
]);

推荐阅读