Обратный вызов в функции vanilla JS не всегда работает? - PullRequest
0 голосов
/ 27 мая 2020

Я написал небольшую ванильную JS функцию для использования объекта XMLHttpRequest. Мне нужно вернуть обратный вызов, но по какой-то причине я могу заставить обратный вызов работать только с функцией onreadystatechange, мне нужно, чтобы он работал с моими ontimeout и onerror ...

My function:

function makeHttpRequest (type, url, timeout, callback) {
  const xhr = new XMLHttpRequest()

  xhr.open(type, url, true)
  xhr.timeout = timeout
  xhr.ontimeout = () => {
    callback.apply('timeout error')
  }

  xhr.onreadystatechange = () => {
    if (xhr.readyState === 4 && xhr.response != null) {
      callback.apply(xhr)
    }
  }

  xhr.onerror = () => {
    callback.apply('generic error')
  }

  xhr.send()
}

Как я использую функцию:

makeHttpRequest('GET', url, timeout, function() {
  const res = this.response != '' ? this.response : JSON.stringify({})
  // ...
})

this.response ничего не содержит при использовании по таймауту и ​​ошибке.

1 Ответ

1 голос
/ 27 мая 2020

Метод apply устанавливает аргумент функции this в ее первый параметр. Когда происходит тайм-аут или возникает ошибка, вы вызываете apply следующим образом:

callback.apply('timeout error');

Таким образом, значение this является строкой. Если вы ознакомитесь с документацией для javascript строк , вы увидите, что объект String не имеет свойства .response. Поэтому 'timeout error'.response ничего не содержит (это undefined).

Если вы хотите, чтобы this.response содержал сообщение об ошибке, не передавайте строку как this. Вместо этого передайте его как .response:

let error = {
    response: 'timeout error'
}

callback.apply(error)

Или проще:

callback.apply({ response: 'timeout error' })
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...