Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

The solution of time-out Asynchronous Operation in JavaScript Front end

2025-01-17 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/02 Report--

Today, I will talk to you about the solution to the JavaScript front-end timeout asynchronous operation, which may not be well understood by many people. in order to make you understand better, the editor has summarized the following content for you. I hope you can get something according to this article.

Since the release of ECMAScript's Promise ES2015 and async/await ES2017 features, asynchrony has become a particularly common operation in the front end. There are some differences in the order in which asynchronous code and synchronous code deal with problems, and writing asynchronous code requires a different "consciousness" from writing synchronous code.

What happens if a piece of code cannot be executed for a long time?

If this is synchronous code, we will see a phenomenon called "unresponsive" or, in popular terms, "dead"; but what if it is a piece of asynchronous code? We may not be able to wait for the result, but the other code continues as if it didn't happen.

Of course, it is not true that things have not happened, but different phenomena will occur under different circumstances. For example, pages with loaded animations seem to be loading all the time; for example, pages that should be updated with data do not see data changes.

Another example is a dialog box that can't be closed. These phenomena are collectively called BUG. But there are also times when an asynchronous operation does not "echo", it just dies there silently, no one knows that after the page is refreshed, not even a trace will be left.

Axios has its own timeout handling.

Using Axios to make Web Api calls is a common asynchronous operation. Usually our code would look like this:

Try {const res = await axios.get (url, options); / / TODO normally carries out subsequent business} catch (err) {/ / TODO for fault-tolerant processing, or error reporting}

This code generally works well until one day the user complains: why didn't you respond after waiting for a long time?

Then the developer realized that due to the increased pressure on the server, it was difficult for the request to respond instantly. Taking into account the feelings of users, add a loading animation:

Try {showLoading (); const res = await axios.get (url, options); / / TODO normal business} catch (err) {/ / TODO fault tolerant processing} finally {hideLoading ();}

One day, however, a user said, "I've been waiting for half an hour, but I've been going in circles!" So the developer realized that, for some reason, the request was jammed, in which case the request should be resent or reported directly to the user-well, a timeout check should be added.

Fortunately, Axios does handle timeouts, and you only need to add a timeout: 3000 to options to solve the problem. If you time out, you can detect and process it in the catch block:

Try {...} catch (err) {if (err.isAxiosError & & err.response & & err.request & & err.message.startsWith ("timeout")) {/ / if it is a request error of Axios and the message is a delay message / / TODO processing timeout}} finally {...}

Axios is fine. What if I use fetch ()?

Processing fetch () timeout

Fetch () does not have the ability to handle the timeout itself, so we need to trigger the "cancel" request operation through AbortController after judging the timeout.

If you need to interrupt a fetch () operation, simply take the signal from an AbortController object and pass in the signal object as an option for fetch (). That's something like this:

Const ac = new AbortController (); const {signal} = ac;fetch (url, {signal}). Then (res = > {/ / TODO processing Business}); / / cancel the fetch operation setTimeout (() = > ac.abort (), 1000) after 1 second

Ac.abort () signals signal, triggers its abort event, and sets its .aborted property to true. The internal processing of fetch () uses this information to abort the request.

The above example shows how to implement timeout handling for the fetch () operation. If you use the form of await to handle it, you need to put setTimeout (...) Put it in fetch (...) Before:

Const ac = new AbortController (); const {signal} = ac;setTimeout (() = > ac.abort (), 1000); const res = await fetch (url, {signal}). Catch (() = > undefined)

To avoid using try... Catch... To process the request failed, here a .catch (...) is added after fetch (). Ignoring the wrong situation. If an error occurs, res is assigned to undefined. Actual business processing may require more reasonable catch () processing to make res contain recognizable error messages.

It would have been done here, but it would be tedious to write such a long piece of code for each fetch () call, so let's wrap it up:

Async function fetchWithTimeout (timeout, resoure, init = {}) {const ac = new AbortController (); const signal = ac.signal; setTimeout (() = > ac.abort (), timeout); return fetch (resoure, {... init, signal});}

Are we done? No, there's a problem.

If we are in the setTimeout (...) of the above code Output a message in:

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

And give enough time in the call:

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

We will see the output success, and we will see the output It's timeout after 5 seconds.

By the way, although we are fetch (...) Handled the timeout, but not in fetch (...) Kill timer if you succeed. As a thoughtful programmer, how can he make such a mistake? Kill him!

Async function fetchWithTimeout (timeout, resoure, init = {}) {const ac = new AbortController (); const signal = ac.signal; const timer = setTimeout (() = > {console.log ("It's timeout"); return ac.abort ();}, timeout); try {return await fetch (resoure, {... init, signal});} finally {clearTimeout (timer);}}

Perfect! But the problem is not over.

Everything can time out.

Both Axios and fetch provide a way to interrupt asynchronous operations, but what about a normal Promise that doesn't have the ability to abort?

As for such a Promise, all I can say is, let him go and let him work for the rest of his life-I can't stop it anyway. But life has to go on. I can't wait forever.

In this case, we can encapsulate setTimeout () into a Promise, and then use Promise.race () to achieve "out of date without waiting":

Race means racing, so is the behavior of Promise.race () easy to understand?

Function waitWithTimeout (promise, timeout, timeoutMessage = "timeout") {let timer; const timeoutPromise = new Promise ((_, reject) = > {timer = setTimeout (() = > reject (timeoutMessage), timeout);}); return Promise.race ([timeoutPromise, promise]) .finally (() = > clearTimeout (timer)); / / Don't forget to clear timer}

You can write a Timeout to simulate the effect:

(async () = > {const business = new Promise (resolve = > setTimeout (resolve, 1000 * 10)); try {await waitWithTimeout (business, 1000); console.log ("[Success]");} catch (err) {console.log ("[Error]", err); / / [Error] timeout}} () After reading the above, do you have any further understanding of the solution to the JavaScript front-end timeout asynchronous operation? If you want to know more knowledge or related content, please follow the industry information channel, thank you for your support.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report