1. Basic use

Fetch is a new interface for retrieving resources on the end, replacing the cumbersome XMLHttpRequest. It has the concept of Request and Response, as well as Headers objects, which are closer to backend language requests for resources.

  • A simple GET request

    fetch('https://www.baidu.com')
            .then(resp= >resp.text())  // Convert to a text object
            .then(resp= >console.log(resp))  // Output the requested content
            .catch(error= > console.error(error));
    Copy the code
  • A simple POST request

    fetch('https://www.easy-mock.com/mock/5ca59ba44ba86c23d507bd40/example/getUser', {method:"post"})
            .then(resp= >resp.json())  // Convert to Json object
            .then(resp= >console.log(resp)) // Outputs the Json content
            .catch(error= > console.error(error));
    Copy the code

    For more details on Fetch, see the MDN documentation developer.mozilla.org/en-US/docs/…

2. Timeout Settings

You can set the request timeout using XMLHttpRequest, but when Fetch is used, the timeout setting is gone, which is often useful when the network is unreliable

After ES6, Promises emerged to address inelegant code styles like the hell callback. Personally, to understand this more as a producer-consumer relationship, look at the Promise document in two ways

  1. Promise.race([promise1,promise2]) passes in multiple Promise objects and waits for the fastest one to complete
  2. Promise.all([promise1,promise2]) passes in multiple Promise objects and waits for them all to complete

With that in mind, you can use the function setTimeout to set the timeout

//ahutor:herbert qq:464884492
let timeoutPromise = (timeout) = > {
    return new Promise((resolve, reject) = > {
        setTimeout((a)= > {
            resolve("I'm a timeoutPromise. I've done it.");
        }, timeout);
    });
}
let requestPromise = (url) = > {
    return fetch(url);
};
Promise.race([timeoutPromise(1000), requestPromise("https://www.baidu.com")])
    .then(resp= > {
        console.log(resp);
    })
    .catch(error= > {
        console.log(error);
    });
Copy the code

3. Cancel the request

Copy the above code to the browser console and set network to Slow3G. When we run it, we see that even though we see a timeout message on the console, switching to the NetwOK TAB shows that the request is still in progress and returns the correct content. This is not what I want, and I expect the timeout to run out and the request to terminate.

After a successful fetch request, a Response object is returned by default, so how do we construct such an object in our code?

  timeoutResp=new Response("timeout", { status: 504.statusText: "timeout " })
  successResp=new Response("ok", { status: 200.statusText: "ok " })
Copy the code

AbortController is used to manually terminate one or more DOM requests in the Fetch request injected by the AbortSignal of this object. So you need to implement the timeout function perfectly and add this to it

//ahutor:herbert qq:464884492
let controller = new AbortController();
let signal = controller.signal;

let timeoutPromise = (timeout) = > {
    return new Promise((resolve, reject) = > {
        setTimeout((a)= > {
            resolve(new Response("timeout", { status: 504.statusText: "timeout " }));
            controller.abort();
        }, timeout);
    });
}
let requestPromise = (url) = > {
    return fetch(url, {
        signal: signal
    });
};
Promise.race([timeoutPromise(1000), requestPromise("https://www.baidu.com")])
    .then(resp= > {
        console.log(resp);
    })
    .catch(error= > {
        console.log(error);
    });
Copy the code

4. To summarize

When USING FETCH for the first time in a project, I found that FETCH had no timeout setting during apI-oriented programming. I checked the MDN document at the first time and looked for inspiration to implement the function from the search engine (copy+ C). Some friends implement setTimeout with reject(New Error(‘ network timeout ‘)). This simply tells the front end that the current request has timed out, without actually terminating the request. So you have to use the AbortSignal object. This feature is still experimental and should be used with caution.