首页 > 作文

JavaScript前端超时异步操作完美解决过程

更新时间:2023-04-03 22:51:41 阅读: 评论:0

目录
如果一段代码久久不能执行完成,会怎么样?axios 自带超时处理处理 fetch() 超时万物皆可超时

自从 ecmascript 的 promies2015和 async/awaites2017特性发布以后,异步在前端界已经成为特别常见的操作。异步代码和同步代码在处理问题顺序上会存在一些差别,编写异步代码需要拥有跟编写同步代码不同的“意识”。

如果一段代码久久不能执行完成,会怎么样?

如果这是同步代码,我们会看到一种叫做“无响应”的现象,或者通俗地说 —— “死掉了”;但是如果是一段异步代码呢?可能我们等不到结果,但别的代码仍在继续,就好像这件事情没有发生一般。

当然事情并不是真的没发生,只不过在不同的情况下会产生不同的现象。比如有加载动画的页面,看起来就是一直在加载;又比如应该进行数据更新的页面,看不到数据变化;

再比如一个对话框,怎么也关不掉 …… 这些现象我们统称为 bug。但也有一些时候,某个异步操作过程并没有“回显”,它就默默地死在那里,没有人知道,待页面刷新之后,就连一点遗迹都不会留下。

axios 自带超时处理

使用 axios 进行 web api 调用就是一种常见的异步操作过程。通常我们的代码会这样写:

try {    const res = await axios.get(url, options);    // todo 正常进行后续业务} catch(err) {    // todo 进行容错处理,或者报错}

这段代码一般情况下都执行良好,直到有一天用户抱怨说:怎么等了半天没反应?

然后开发者意识到,由于服务器压力增大,这个请求已经很难瞬时响应了。考虑到用户的感受,加了一个 loading 动画:

try {    showloading();    const res = await axios.get(url, options);    // todo 正常业务} catch (err) {    // todo 容错处理} finally {    hideloading();}

然而有一天,有用户说:“我等了半个小时,居然一直在那转圈圈!”于是开发者意识到,由于某种原因,请求被卡死了,这种情况下应该重发请求,或者直接报告给用户 —— 嗯,得加个超时检查。

幸运的是 axios 确实可以处理超时,只需要在options里添加一个timeout: 3000就能解决问题。如果超时,可以在catch块中检测并处理:

try {...}catch (err) {    if (err.isaxiorror && !err.respon && err.request        && err.message.startswith("timeout")) {        // 如果是 axios 的 request 错误,并且消息是延时消息        // todo 处理超时    }}finally {...}

axios 没问题了,如果用fetc南昌市教育考试院h()呢?

处理 fetch() 超时

fetch()自己不具备处理超时的能力,需要我们判断超时后通过abortcontroller来触发“取消”请求操作。

如果需要中断一个fetch()操作,只需从一个abortcontroller对象获取signal,并将这个信号对象作为fetch()的选项传入。大概就是这样:

const ac = new abortcontroller();const { signal } = ac;fetch(url, { signal }).then(res => {    // todo 处理业务}); // 1 秒后取消 fetch 操作ttimeout(() => ac.abort(), 1000);

ac.abort()会向signal发送信号,触发它的abort事件,并将其.aborted属性置为truefetch()内部处理会利用这些信息中止掉请求。

上面这个示例演示了如何实现fetch()操作的超时处理。如果使用await的形式来处理,需要把ttimeout(...)放在fetch(...)之前:

const ac = new abortcontroller();const { signal } = ac;ttimeout(() => ac.abort(), 1000);const res = await fetch(url, { signal }).catch(() => undefined); 

为了避免使用try ... catch ...来处理请求失败,这里在fetch()后加了一个.catch(...)在忽略错误的情况。如果发生错误,res会被赋值为undefined。实际的业务处理可能需要更合理的catch()处理来让res包含可识别的错误信息。

本来到这里就可以结束了,但是对每一个fetch()调用都写这么长一段代码,会显得很繁琐,不如封装一下:

async function fetchwi于丹论语thtimeout(timeout, resoure, init = {}) {    const ac = new abortcontroller();    const signal = ac.signal;    ttimeout(() => ac.abort(), timeout);    return fetch(resoure, { ...init, signal });}

没问题了吗?不,有问题。

如果我们在上述代码的ttimeout(...)里输出一条信息:

ttimeout(() => {    console.log("it's timeout");    ac.abort();}, timeout);

并且在调用的给一个足够的时间:

fetchwithtimeout(5000, url).then(res => console.log("success"));

我们会看到输出success,并在 5 秒后看到输出it's timeout

对了,我们虽然为fetch(...)处理了超时,但是并没有在fetch(...)成功的情况下干掉timer。作为一个思维缜密的程序员,怎么能够犯这样的错误呢?干掉他!

async function fetchwithtimeout(timeout, resoure, init = {}) {    const ac = new abortcontroller();    const signal = ac.signal;        const timer = ttimeout(() => {        console.log("it's timeout");        retur成长路上无捷径n ac.abort();    }, timeout);        try {        return await fetch(resoure, { ...init, signal });    } finally {        cleartimeout(timer);    }}

完美!但问题还没结束。

万物皆可唯美背影图片超时

axios 和 fetch 都提供了中断异步操作的途径,但对于一个不具备abort能力的普通 promi 来说,该怎么办?

对于这样的 promi,我只能说,让他去吧,随便他去干到天荒地老 —— 反正我也没办法阻止。但生活总得继续,我不能一直等啊!

这种情况下我们可以把ttimeout()封装成一个 promi,然后使用promi.race()来实现“过时不候”:

race 是竞速的意思,所以promi.race()的行为是不是很好理解?

function waitwitht参观博物馆imeout(promi, timeout, timeoutmessage = "timeout") {    let timer;    const timeoutpromi = new promi((_, reject) => {        timer = ttimeout(() => reject(timeoutmessage), timeout);    });     return promi.race([timeoutpromi, promi])        .finally(() => cleartimeout(timer));    // 别忘了清 timer}

可以写一个 timeout 来模拟看看效果:

(async () => {    const business = new promi(resolve => ttimeout(resolve, 1000 * 10));    try {        await waitwithtimeout(business, 1000);        console.log("[success]");    } catch (err) {        console.log("[error]", err);    // [error] timeout    }})();

以上就是javascript前端超时异步操作完美解决的详细内容,更多关于解决前端超时的异步操作的资料请关注www.887551.com其它相关文章!

本文发布于:2023-04-03 22:51:39,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/zuowen/182dd4228c948754bf42c117020722d3.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

本文word下载地址:JavaScript前端超时异步操作完美解决过程.doc

本文 PDF 下载地址:JavaScript前端超时异步操作完美解决过程.pdf

下一篇:返回列表
标签:代码   操作   情况下   业务
相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图