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

2021-02-18 23:26:14 +08:00
 liudaqi
页面上有一个外部地图数据统计的 API 请求,通常会有 2~3 秒的延时,数据好了再异步加载显示。

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

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

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

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

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/754073

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX