You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

每个Promise的超时未重置问题求助(Mapbox地图下载场景)

问题根源

你当前代码的核心问题在于:bufferedCellBBoxes.map会同步遍历所有单元格,一次性为每个cell创建60秒超时定时器——所有定时器在同一时刻启动计时。哪怕某个cell的下载在10秒内完成,对应的定时器依然会继续运行,到点后触发超时逻辑;同时你没有在下载完成时标记超时已处理,导致定时器回调仍会执行,进而出现“频繁触发超时”的现象。

修复方案

方案1:完善超时标记+清除定时器

在下载完成或出错时,立即标记超时已处理并主动清除定时器,彻底避免后续无效的超时回调:

const downloads = bufferedCellBBoxes.map(async (cell, i) => {
    let timeoutResolved = false;
    let timeoutId; // 保存定时器ID

    const timeoutPromise = new Promise((resolve) => {
        timeoutId = setTimeout(() => {
            if (!timeoutResolved) {
                resolve('timeout');
                timeoutResolved = true;
            }
        }, 60000);
    });

    const satellitePromise = downloadMapTiles(
        'satellite',
        [[cell[2] as number, cell[3] as number], [cell[0] as number, cell[1] as number]],
    );

    const streetPromise = downloadMapTiles(
        'street',
        [[cell[2] as number, cell[3] as number], [cell[0] as number, cell[1] as number]],
    );

    try {
        const result = await Promise.race([
            Promise.all([satellitePromise, streetPromise]),
            timeoutPromise,
        ]);
        timeoutResolved = true;
        clearTimeout(timeoutId); // 下载完成,清除定时器
        if (result === 'timeout') {
            throw new Error('Timed out');
        }
        return result;
    } catch (error) {
        timeoutResolved = true;
        clearTimeout(timeoutId); // 出错时也清除定时器
        console.error(`Cell ${i} download error:`, error);
        return Promise.reject(error);
    }
});

方案2:串行处理单元格(逐一下载)

如果你的“每一轮循环”指串行执行下载(完成一个cell再处理下一个),而非并行下载所有,那么不能用map批量启动任务,改用循环串行执行:

async function downloadAllCells() {
    const results = [];
    for (const [i, cell] of bufferedCellBBoxes.entries()) {
        let timeoutResolved = false;
        let timeoutId;

        const timeoutPromise = new Promise((resolve) => {
            timeoutId = setTimeout(() => {
                if (!timeoutResolved) {
                    resolve('timeout');
                    timeoutResolved = true;
                }
            }, 60000);
        });

        const satellitePromise = downloadMapTiles(
            'satellite',
            [[cell[2] as number, cell[3] as number], [cell[0] as number, cell[1] as number]],
        );

        const streetPromise = downloadMapTiles(
            'street',
            [[cell[2] as number, cell[3] as number], [cell[0] as number, cell[1] as number]],
        );

        try {
            const result = await Promise.race([
                Promise.all([satellitePromise, streetPromise]),
                timeoutPromise,
            ]);
            timeoutResolved = true;
            clearTimeout(timeoutId);
            if (result === 'timeout') {
                throw new Error('Timed out');
            }
            results.push(result);
        } catch (error) {
            timeoutResolved = true;
            clearTimeout(timeoutId);
            console.error(`Cell ${i} download error:`, error);
            throw error; // 如需终止后续下载则抛出,否则替换为continue
        }
    }
    return results;
}

// 启动串行下载
downloadAllCells()
    .then(results => console.log('All downloads completed:', results))
    .catch(err => console.error('Download process failed:', err));

内容的提问来源于stack exchange,提问作者MomasVII

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 06:27:43