Где находится обратный вызов исполнителя Promise при запуске асинхронного кода? - PullRequest
1 голос
/ 08 мая 2020

Функция-конструктор Promise может принимать executor callback function, и этот вопрос касается того, где эта функция обратного вызова находится в пространстве выполнения, когда функция обратного вызова исполнителя имеет асинхронный код.

ДЕТАЛИ:

Объект Promise представляет значение, которое может быть еще недоступно, но будет разрешено в какой-то момент в будущем. Он позволяет вам писать асинхронный код, например, при вызове удаленной веб-службы, вы создаете объект Promise, который представляет данные, которые будут возвращены веб-службой в будущем.

Пока не будут доступны фактические данные , объект Promise действует как прокси для фактических данных.

Фрагмент кода ниже описывает эту ситуацию:

function getRandomJoke(){
  return new Promise((resolve, reject) => {
    const request = new XMLHttpRequest();

    request.open('GET', 'https://api.icndb.com/jokes/random');
    request.onload = () => {
      if (request.status === 200) {
        resolve(request.response); // we got data here, so resolve the Promise
      } else {
        reject(Error(request.statusText)); // status is not 200 OK, so reject
      }
    };

    request.onerror = () => {
      reject(Error('Error fetching data.')); // error occurred, reject the  Promise
    };

    request.send(); // send the request
  });
}

Согласно обсуждению в этом потоке , оба Создание обещания и выполнение функции обратного вызова исполнителя происходит в основном потоке, и только обратный вызов разрешения будет выполнен на следующем тике события l oop.

В этом случае функция исполнителя фрагмента кода выше имеет асинхронный код вызова API - будет ли это также зависеть от основного потока, пока API не вернет данные.

1 Ответ

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

В этом случае функция-исполнитель фрагмента кода выше имеет асинхронный код для вызова API - он также будет зависеть от основного потока, пока API не вернет данные.

Нет, он ничего не повесит. request.send() асинхронный и неблокирующий. Когда вы вызываете request.send(), он инициирует отправку запроса (передает его ОС), а затем немедленно возвращается. Сама функция исполнителя обещания возвращается, и тогда основной поток может делать все, что хочет.

Между тем, через некоторое время, базовая операция TCP вызовет вставку события в очередь событий. Когда это событие обрабатывается основным потоком (когда он больше ничего не делает и это событие попадает в очередь событий), объект запроса генерирует событие onload или onerror, а соответствующий слушатель разрешить или отклонить обещание. Это запустит обещание, вызывающее его обработчики .then() или .catch() в будущем тике.

Использование запроса таким образом абсолютно ничем не отличается внутри функции исполнителя обещания, как и где-либо еще в node.js . Он инициирует асинхронную неблокирующую операцию, вы настраиваете некоторые прослушиватели для обратных вызовов, а затем интерпретатор nodejs может делать другие вещи до тех пор, пока позже не произойдет событие завершения и не будут вызваны некоторые обратные вызовы.

Где находится обратный вызов исполнителя Promise при запуске асинхронного кода?

Непонятно, что вы имеете в виду под «где он живет?». Функция исполнителя обещания такая же, как и любая другая функция. Он вызывается синхронно, и когда он возвращает конструктор new Promise(), возвращается и создается обещание, которое может использовать вызывающий код. Через некоторое время это обещание будет выполнено или отклонено (обычно). Частью инициализации и настройки обещания является выполнение функции исполнителя обещания, но это всего лишь один шаг в создании обещания. Эта функция не блокируется, если вы делаете в ней что-то асинхронное.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...