V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a JavaScript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
JavaScript 权威指南第 5 版
Closure: The Definitive Guide
liudaqi
V2EX  ›  JavaScript

JS 怎么在页面实现延时提醒?(外部 API 请求慢 2~3 秒返回数据 | 也可能失连:让用户重新加载一下)

  •  
  •   liudaqi · 10 天前 · 853 次点击
    页面上有一个外部地图数据统计的 API 请求,通常会有 2~3 秒的延时,数据好了再异步加载显示。

    但是,由于这个 API 比较拥挤,可能会请求拒绝,然后在页面上提示用户:如果要看地图展示的统计数据,可以重新刷新一下(不看地图数据展示,并不影响页面其他部分)。

    现在经常会出现错误提示:让用户重新刷新一下,其实是过 2~3 秒之后数据就可以了。

    怎么让这个提示晚 5 秒钟左右再出现?(超过 5 秒数据还没准备好,大概率这次网络请求是拿不到数据了,不是速度慢的情况。这个时候去提醒用户)
    13 条回复    2021-02-20 15:31:52 +08:00
    ferock
        1
    ferock   10 天前 via iPhone
    setTimeOut
    liudaqi
        2
    liudaqi   10 天前
    @ferock setTimeOut 不行,只是把错误的提示延时出现了,还是会出现。

    期望的情况是:5 秒内网络数据加载完了,就不提示;没加载好就提示。
    Zhuzhuchenyan
        3
    Zhuzhuchenyan   10 天前
    Rocketer
        4
    Rocketer   10 天前 via iPhone   ❤️ 6
    Promise.race 会返回第一个执行完成的结果,所以你可以用它同时执行一个 5 秒钟延时的 reject 。如果请求成功了就会忽略这个 reject,如果 5 秒还没成功,就会收到这个 reject 。

    示例代码:

    ```Javascript
    const result = await Promise.race([
    fetch('/your-request-api'),
    new Promise((resolve, reject) => {
    setTimeout(() => reject(‘Timeout’), 5000)
    })
    ]);
    ```
    a570295535
        5
    a570295535   10 天前 via Android
    @liudaqi 前台弄一个 3 个点的 gif 动图显示加载中,ajax 请求地图 api 判断是否返回 200,超时时间设置 5 秒,超时就返回刷新提示
    SilencerL
        6
    SilencerL   10 天前
    楼上 Promise.race 正解, 话说这不是前端基础知识了吗..
    learningman
        7
    learningman   10 天前
    你请求的时候设 timeout,然后把显示提示的代码放 catch 里不就好了
    molvqingtai
        8
    molvqingtai   10 天前
    让用户主动刷新体验不好,请求失败了就自动重试,中途一直显示 loading
    xstmjh
        9
    xstmjh   10 天前
    new Promise(function (resolve, reject) {
    asyncFn(param, function (err, result) {
    if (error) {
    return reject(error);
    }
    return resolve(result);
    });

    setTimeout(function () {
    reject('timeout');
    }, 5000);
    }).then(doSomething);
    ljpCN
        10
    ljpCN   10 天前
    建议楼主详细说说这个错误提示是在什么情形下抛出的。看你的描述,并不是在网络请求失败时抛出的,如果是应该就不存在需要添加延时的问题了。
    Reapper
        11
    Reapper   10 天前
    定时器
    Roger006
        12
    Roger006   10 天前   ❤️ 1
    1 发送请求的时候,同时设置 settimeout [记得保存句柄,清除延时时要用到] ,timer
    2 延时要进行的操作就是提示用户刷新的弹窗方法,此处假设方法名为 waringFn
    3 写一个清理延时的方法,比如 clearTimerFn = ()=>{clearTimeout(timer); timer = null;}
    4 请求本身设定 5 秒超时,catch 里边 [此处捕获异常包含超时、网络问题、端口拒绝等] 调用 waringFn 和 cleaerTimerFn ( catch 里边的操作需要一个判断,判断 timer 是否为 null )
    John60676
        13
    John60676   9 天前
    如果是用 vue3 写的话,可以考虑一下用 vue-request https://github.com/AttoJS/vue-request 来处理,里面有个 错误重试 的模块,应该能解决你面临的问题。
    关于   ·   帮助文档   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   3134 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 19ms · UTC 13:43 · PVG 21:43 · LAX 05:43 · JFK 08:43
    ♥ Do have faith in what you're doing.