JS 怎么在页面实现延时提醒?(外部 API 请求慢 2~3 秒返回数据 | 也可能失连:让用户重新加载一下) - V2EX
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 2021-02-18 23:26:14 +08:00 2693 次点击
    这是一个创建于 1696 天前的主题,其中的信息可能已经有所发展或是发生改变。
    页面上有一个外部地图数据统计的 API 请求,通常会有 2~3 秒的延时,数据好了再异步加载显示。

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

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

    怎么让这个提示晚 5 秒钟左右再出现?(超过 5 秒数据还没准备好,大概率这次网络请求是拿不到数据了,不是速度慢的情况。这个时候去提醒用户)
    14 条回复    2021-03-11 18:25:27 +08:00
    ferock
        1
    ferock  
    PRO
       2021-02-18 23:28:37 +08:00 via iPhone
    setTimeOut
    liudaqi
        2
    liudaqi  
    OP
       2021-02-18 23:38:12 +08:00
    @ferock setTimeOut 不行,只是把错误的提示延时出现了,还是会出现。

    期望的情况是:5 秒内网络数据加载完了,就不提示;没加载好就提示。
    Zhuzhuchenyan
        3
    Zhuzhuchenyan  
       2021-02-18 23:42:41 +08:00
    Rocketer
        4
    Rocketer  
       2021-02-18 23:50:57 +08:00 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  
       2021-02-18 23:51:33 +08:00 via Android
    @liudaqi 前台弄一个 3 个点的 gif 动图显示加载中,ajax 请求地图 api 判断是否返回 200,超时时间设置 5 秒,超时就返回刷新提示
    SilencerL
        6
    SilencerL  
       2021-02-19 00:28:37 +08:00
    楼上 Promise.race 正解, 话说这不是前端基础知识了吗..
    learningman
        7
    learningman  
       2021-02-19 00:38:47 +08:00
    你请求的时候设 timeout,然后把显示提示的代码放 catch 里不就好了
    molvqingtai
        8
    molvqingtai  
       2021-02-19 00:41:52 +08:00
    让用户主动刷新体验不好,请求失败了就自动重试,中途一直显示 loading
    xstmjh
        9
    xstmjh  
       2021-02-19 00:42:25 +08:00
    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  
       2021-02-19 01:47:07 +08:00
    建议楼主详细说说这个错误提示是在什么情形下抛出的。看你的描述,并不是在网络请求失败时抛出的,如果是应该就不存在需要添加延时的问题了。
    Reapper
        11
    Reapper  
       2021-02-19 13:33:26 +08:00
    定时器
    Roger006
        12
    Roger006  
       2021-02-19 13:49:55 +08:00   1
    1 发送请求的时候,同时设置 settimeout [记得保存句柄,清除延时时要用到] ,timer
    2 延时要进行的操作就是提示用户刷新的弹窗方法,此处假设方法名为 waringFn
    3写一个清理延时的方法,比如 clearTimerFn = ()=>{clearTimeout(timer); timer = null;}
    4 请求本身设定 5 秒超时,catch 里边 [此处捕获异常包含超时、网络问题、端口拒绝等] 调用 waringFn 和 cleaerTimerFn ( catch 里边的操作需要一个判断,判断 timer 是否为 null )
    John60676
        13
    John60676  
       2021-02-20 15:31:52 +08:00
    如果是用 vue3 写的话,可以考虑一下用 vue-request https://github.com/AttoJS/vue-request 来处理,里面有个 错误重试 的模块,应该能解决你面临的问题。
    zeni123
        14
    zeni123  
       2021-03-11 18:25:27 +08:00
    楼主是不是想让外部的 API 延迟发出, 假如外部 API 是打包好的那么只能拦截 XMLHttpRequest 和 send 方法 5 秒钟了...

    下面代码只是示例,还不能运行

    var sendFunc = XMLHttpRequest.prototype.send;
    XMLHttpRequest.prototype.send = function (data) {

    console.log("wait for 5 seconds before sending a request")
    setTimeout(function () {
    console.log("sending data now");
    sendFunc(data);
    }, 5000);
    };
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     879 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 25ms UTC 21:48 PVG 05:48 LAX 14:48 JFK 17:48
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86