Невозможно добавить время ожидания для Windows.Web.Http.HttpClient в JavaScript

Мне очень трудно понять, как установить время ожидания запроса с помощью Windows.Web.HttpClient, доступного через WinRT. Приложение, над которым я работаю, представляет собой универсальное приложение для Windows типа JavaScript. «на стороне клиента» JavaScript имеет доступ к использованию различных пространств имен, которые обычно используются при программировании на C#. К членам этих пространств имен можно получить доступ из объекта окна следующим образом:

const {
  HttpRequestMessage,
  HttpMethod,
  HttpClient,
} = R.pathOr({}, ['Windows', 'Web', 'Http'], window);

Цель кода, который я опубликую ниже, состоит в том, чтобы выполнить простую проверку доступности URL-адреса до того, как приложение перенаправит его туда, и в случае, если кто-то задается вопросом, почему я просто не сделал этого, используя более стандартные средства в JavaScript (например, XMLHttpRequest ), это связано с тем, что CORS иногда не выполняет эти запросы. Поскольку я работаю в крупной компании, не так-то просто потребовать, чтобы везде добавлялись правильные заголовки access-control-allow-origin, и, кроме того, у нас есть тестеры, которые загружаются на устройства, запускают прокси и т. д.

Тем не менее, хотя мне удалось найти документацию с некоторым отношением к рассматриваемой задаче, все примеры написаны на C#, и я заметил, что не все, что касается JavaScript, идеально согласуется с этой документацией.

Пользователь Stack Overflow задал очень похожий вопрос здесь, и было принято решение: используйте CancellationTokenSource. Однако, насколько мне известно, решение этой проблемы на C# не относится к стороне JavaScript, но я нашел почти решение, в котором я могу отменить задачу, используя setTimeout. Обратите внимание, что я отредактировал здесь некоторые строки кода для удобства чтения.

const isReachable = async (url) => (
  new Promise((resolve) => {
    const message = new HttpRequestMessage();
    message.method = new HttpMethod('HEAD');
    message.requestUri = new Uri(url);
    const client = new HttpClient();
    const task = client.sendRequestAsync(message);
    const timeout = setTimeout(() => task.cancel(), 5000);
    task.done(
      (result) => { // Success
        clearTimeout(timeout);
        resolve(true);
      },
      (result) => { // Failure
        clearTimeout(timeout);
        resolve(false);
      },
    );
  })
);

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

Это была моя следующая (частичная) попытка, и, по-видимому, если я подожду ответа, то действительно получу объект, достаточно похожий на ответ XHR, который можно использовать для этой цели. Однако, поскольку я ожидаю задачи здесь, я не сохраняю ее в переменной, чтобы ее можно было отменить после истечения времени ожидания.

const urlIsReachable = async (url = '') => (
  new Promise(async (resolve) => {
    const request = new HttpRequestMessage();
    request.method = new HttpMethod('HEAD');
    request.requestUri = new Uri(url);
    const client = new HttpClient();
    const response = await client.sendRequestAsync(request);
    const { statusCode: status } = response;
    if (status === 200) {
      resolve(true);
      return;
    }
    resolve(false);
  })
);

В заключение, я не думал, что такая простая вещь, как установка порога тайм-аута, будет такой головной болью, но я не смог найти способ сделать это.


person Joshua Dannemann    schedule 27.08.2019    source источник


Ответы (1)


  1. #P1# <цитата> #P2# #P3#
  2. #P4#
    #P5#
    task.done(
        (result) => { // Success
            clearTimeout(timeout);
            resolve(true);
        },
        (result) => { // Failure
            let msg=result.message;//message is 'Canceled' if timeout callback's called
            clearTimeout(timeout);
            resolve(false);
        },
    );
    
person Elvis Xia - MSFT    schedule 05.09.2019