At work, we may encounter situations where we need to download a file or video and provide users with real-time progress

The first thing that comes to mind is to use fetch (the browser-provided request method). Fetch supports tracking and showing progress and provides a response.body property.

Let’s take a look at the implementation

Start by creating an index.html to display the progress details

   <div>Progress:<span class="VALUE">0</span>%
        <p id="LINE"></p>
    </div>

Copy the code

Add some styles

  <style>* {padding: 0;
            margin: 0;
        }
        #LINE {
            height: 20px;
            width: 0;
            background: purple;
            color: #fff;
            text-align: right;
            padding-right: 20px;
            box-sizing: border-box;
        }
    </style>
Copy the code

We need to start a service to write interfaces and read locallyindex.html(Solve cross-domain problems by the way)

Create server.js and start Node Server

const http = require('http')
const fs = require('fs')

const server = http.createServer((req, res) = > {

    if (req.url === '/') {
        res.writeHead(200, { 'Content-Type': 'text/html; charset=UTF-8' })

        const html = fs.readFileSync('./index.html'.'utf-8')

        res.end(html)
    } else if (req.url === '/api') {
        let data = ' '
        // We play a video mv1.mp4 in our directory for interface reading
        let readerStream = fs.createReadStream('./mv1.mp4');

        readerStream.on('data'.function (chunk) {
            data += chunk;
        })

        readerStream.on('end'.function () {
            res.writeHead(200, { 'Content-Type': 'video/mp4' })
            res.end(JSON.stringify(data))
        });

    }
})



server.listen(8080.() = > console.log('Starting.... '))
Copy the code

So let’s go ahead and writeindex.htmlThe inside of thejslogic

 Response. body has a getReader() method * 3. We need to loop through the getReader().read method * 4. An object containing done and value is returned. If done is true, the read is complete * 5. The above is our specific logic */
Copy the code
// Create a method
async function getValue() {
  	
  // Use fetch to fetch our written interface
	const response = await fetch('http://localhost:8080/api');
  const reader = response.body.getReader();
	
  // By the way, we want to get the size of the returned data by using content-length to get the Length of bytes. Size in NetWork represents the size of the entire request body
  const contentLength = +response.headers.get('Content-Length');
  
  // Set the initial value
  let count = 0
	
  VALUE.innerHTML = count
  
  let receiveLength = 0 // Receive the currently loaded bytes
  
  let chunks = [] // Array of binary blocks received (including body)
  
  // Loop through the reader.read() method
   while (true) {
     const {
       done,
       value
     } = await reader.read()

     if (done) {
       VALUE.innerHTML = 100
       break;
     }
     VALUE.innerHTML = VALUE.innerHTML < 99 ? ++count : VALUE.innerHTML
     LINE.style.width = VALUE.innerHTML < 99 ? ++count + The '%' : VALUE.innerHTML + The '%'
     chunks.push(value);
     receiveLength += value.length
   }
  
  //Uint8Array array type represents an array of 8-bit unsigned integers that are initialized to 0 when created. Once created, you can refer to the elements of the array as objects or by using an array subscript index.
  
  let chunkAll = new Uint8Array(receiveLength)
  let position = 0
	
  TextDecoder is used to parse the value after placing it in chunkAll (TextDecoder interface represents a TextDecoder, a decoder only supports a specific text encoding, such as utf-8, iso-8859-2, koi8, cp1261, GBK, etc.). The decoder takes a byte stream as input and provides a stream of code points as output.)
  
  for (let chunk of chunks) {
    chunkAll.set(chunk, position)
    position += chunk.length
  }
	
  // The final result
  let res = new TextDecoder('utf-8').decode(chunkAll)
  
}
Copy the code

This is the end of the data download presentation

Following up on an interview question, some interviewers sometimes ask: How do I interrupt a request?

There are two commonly used types of request: Axios or FETCH

Axios provides a method called cancelToken
const CancelToken = axios.CancelToken;
CancelToken CancelToken has a source() method
const source = CancelToken.source();
//3. Then continue to call the cancel method provided in source to cancel the request and pass in some hints
source.cancel('tip')
Copy the code
AbortController The AbortController interface represents a controller object that allows you to abort one or more Web requests as needed
const controller = new AbortController();
//2. Fetch needs to fetch signal
const signal = controller.signal;
//3. Perform the fetch request
fetch(url, {signal}).then(function(response) {})
//4. Call abort when you want to interrupt
controller.abort();

Copy the code

The end Thank You