preface

During the development of a VUE project, I encountered a requirement to interrupt file upload. When I used AXIos’ Cancel token to implement the function of interrupt request, I wanted to send post request again, but AXIos directly returned reject.

Documentation about cancel tokens in AXIos

const CancelToken = axios.CancelToken; const source = CancelToken.source(); axios.get('/user/12345', { cancelToken: source.token }).catch(function(thrown) { if (axios.isCancel(thrown)) { console.log('Request canceled', thrown.message); } else {// handle error}}); axios.post('/user/12345', { name: 'new name' }, { cancelToken: Source.token}) // Cancel the request (the message argument is optional) source.cancel('Operation Canceled by the user.'); Canceltoken.source () method generates a source object // (the source object has a cancel method and a token object) // 2. In the requested config, assign source.token to the cancelToken attribute // 3 of config. To cancel a request after it has been sent, execute the cancel method of a sourced objectCopy the code

My implementation scheme

// fileObj: file object // source: Upload source object generated by axios.canceltoken.source () source) { const formData = new FormData() formData.append('file', fileObj) return server.post(url, formData, { timeout: 9999999, // to prevent timeout cancelToken: Source. The token / / use surce. Token tag request})} -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - the upload. Vue upload files import components axios from 'axios' export default { data() { const source = axios.CancelToken.source() return{ source, // Store source in data fileObj: Async upload(){let res = null try {res = await this.$api.upload(this.fileobj, This.source)} catch (e) {console.log(e.message)}}, cancelReauest() {this.source. Cancel ('stop')}}}Copy the code

Problem of repetition

  • When I performuploadMethod, the file can be uploaded normally
  • Click the interrupt button to executecancelReauestMethod, file upload interrupts, console prints error messagestop
  • Upload the file again and runuploadMethod, the request is interrupted, the error is caught by a catch, and the console prints an error messagestop

According to my understanding, I did not execute cancelReauest method at this time, and the file should be uploaded normally, but the request was directly interrupted at this time, which was difficult to understand. There was no similar problem or solution after searching Google and Baidu, so I had to explore by myself

Guess and understand

Before executing the cancelReauest method, I print the Source object, look at its data structure, and see that there is a Promise object under its token, which is now in a pending state

After I execute the cancelReauest method, the state of the promise becomes progressively, and there is a Reason object, which contains the message stop that I passed last time to stop uploading the file

Therefore, I venture to guess that the interruption of file uploading is controlled according to the state of the promise under source.token

  • When the state ofpending“, the file can be uploaded normally
  • When the state offulfilledFile uploading is interrupted

And in my code, after the file upload breaks

  • Stored in thedataIn thesourceObject, whichtokenIn thepromiseThe status has been changed tofulfilled
  • When I send the request again,configIs carried by the statefulfilledthesourceObject, all requests are interrupted directly

To test my guess, I reassigned the source object to refresh its Promise state after the file upload was interrupted

CancelReauest () {this.source.cancel('stop') this.source = axios.canceltoken.source () // reassign}Copy the code

After the modification, when I send the request again, upload successfully!

Problem solved, end scatter flowers!