Синхрония vs. Asincronía, чтобы подбирать данные в реальном времени с javascript

Как хорошо он говорит титул, я сталкиваюсь с перекрестком относительно как использовать методы собирания информации (файл json в маршруте), если делать это синхронным или асинхронным способом.

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

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

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

Прямо сейчас у меня есть этот код, чтобы подбирать данные:

//URL para obtener los datos.
var requestURL = "data.geojson";
//Objeto de petición.
var request = new XMLHttpRequest();
//Métodos para realizar una petición de datos a una URL, mediante el método GET y con una cabecera personalizada.
request.open('GET', requestURL, false);
request.send();
if ((request.readyState == 4) && (request.status === 200)) {
    data = request.responseText;
}
9
задан 05.03.2019, 10:29
2 ответа

Лучшая форма состоит в том, чтобы использовать класс Promise, чтобы делать вызовы as¦-ncronas имея возможность "надеяться" получить результат, чтобы выполнять c¦digo, который ты хочешь, даже, если у тебя есть список вызовов, ты они можешь añadir в array и выполнять блок c¦digo, однажды покончили все с Promise.all(arrayDePromesas).then(... Ты имеешь mÃ: s informaci¦n в documentaci¦n .

В твоем случае для c¦digo, который ты поместил, ты можешь использовать следующего método, который я сам использую в моем c¦digo:

function request(method, url, body = "") {
    return new Promise(function (resolve, reject) {
        var xhr = new XMLHttpRequest();
        xhr.open(method, url);
        xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
        xhr.onload = function () {
            if (this.status >= 200 && this.status < 300) {
                resolve(xhr.response);
            } else {
                reject({
                    status: this.status,
                    statusText: xhr.statusText
                });
            }
        };
        xhr.onerror = function () {
            reject({
                status: this.status,
                statusText: xhr.statusText
            });
        };

        if(method === "POST"){
            xhr.send(body);
        }
        else{
            xhr.send();
        }
    });
}

и вызов ser¦ - в:

request('GET', requestURL)
  .then(function (response) {
    console.log(response);
  });

then только будет работать, когда у тебя есть ответ сервера и он называется в método resolve (в который ты перемещаешь его данные, которые равняются переменной response)

, Если ты хочешь использовать интервал ser¦ - в следующего способа:

setInterval(function(){ 
    request('GET', requestURL)
      .then(function(response){
        /*comprobar si los datos coinciden*/ 
      });
  }, 15000);
11
ответ дан 03.12.2019, 04:09
  • 1
    Конечная цель, которую я ищу несмотря на то, что получаю внешние данные json, состоит в том, чтобы применять эту informació n, который я подбираю в карту, рисуя элементы в положениях geográ ficas ты делаешь конкретным, думаешь, что serí в ú til использовать это? –  Pelayo 21.05.2018, 14:57
  • 2
    не только ú til, но я думаю, что это лучший способ делать вызовы в любом случае –  David 21.05.2018, 17:37
  • 3
    Вопрос má s, tratarí в собирания informació n " реальный time" тогда, ¿ qué aplicarí в setInterval в весь js?, или, ¿ в обещание? –  Pelayo 21.05.2018, 17:56
  • 4
    завись от для того, чтобы ты захотел использовать setInterval, для qué ты хочешь использовать это? –  David 21.05.2018, 18:20
  • 5
    я обновил это тебе в ответе для того, чтобы ты видел как serí в с интервалом –  David 22.05.2018, 11:27

Прежде всего, нужно понимать ясно, как функционирует модель событий языка сценариев JavaScript. Это фундаментальное и обусловливает полностью функционирование и способ работать с языком. И он extraordinarimante просто:

  1. Переводчик НИЧЕГО НЕ ДЕЛАЕТ до тех пор, пока событие fuerze в это.

    В Ваших натуральное состояние , язык не estГЎ не реализовывая ни одной acciГіn . Он ограничивается тем, чтобы ждать, не тратя едва времени CPU, за которым событие последовало бы.
  2. Совсем funciГіn язык сценариев JavaScript работает БЕЗ INTERRUPCIГ “N до конца.

    Это включает возможные призывы к другим функциям. совсем последовательность действий и вызовов ты усиливаешься он производит себе до тех пор, пока не достигают return ее funciГіn первичная , или производит одну себе excepciГіn (этот Гєnico случай , в котором не достигают return ее funciГіn первичная).

, Чтобы это реализовывать, язык основывается на 3 элемента:

  1. Функция callback .
  2. Батарейка вызовов.
  3. Очередь событий.

Функций callback :

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

В языке сценариев JavaScript, какие-то типы (nГєmeros, цепи) перемещают себя из-за копии ; другие, больше комплексы (объекты, array s), из-за ссылки . Так как одной funciГіn callback только ссылка на одну funciГіn .

Ваше использование - то же самое, что тот любого другого типа информации: реализовывать действия с нею; но, хотя в объекте мы можем, например, изменять Ваш контент, Гєnica acciГіn, чтобы реализовывать с одной funciГіn, , его называет ее , делая nombre( ).

Например, в setTimeout( mifuncion, 1000 ), мы перемещая , как я доказываю callback : ссылка на одну funciГіn, что serГЎ выполненная в algГєn будущий момент (aprox. 1 segudo в будущем).

AquГ - вводят в игру завершение ( closures в inglГ©s). Чтобы не увеличивать нас, я уполномочиваю в ВїCГіmo функционируют закрытия в языке сценариев JavaScript? ].

Батарейка:

- внутренняя структура языка, в которой они уходят складывая в штабели различные так называемые функции. Каждый раз, когда, с одной funciГіn, он называет другую, это хранится в батарейке. Когда заканчивают ее ejecuciГіn одной funciГіn, он консультируется в батарейке , куда мы должны возвращать . Цикл повторяется до тех пор, пока батарейка estГ© vacГ - в, что показывает, что закончило работать все cГіdigo и переводчик может ставить до тех пор, пока он не получит другое событие.

Очередь событий:

События могут случаться в любом моменте и в любой команде. Если intГ©rprete estГЎ выполняя один cГіdigo в данном моменте, и случается новое событие, этот хранится в очереди до тех пор, пока не прибудет Ваша очередь быть проанализированным и реализовывать ее acciГіn партнер.
Это производит себе формы невидимых для нас. Действительно, наш cГіdigo язык сценариев JavaScript не сообщает себе о, если случились новые события, до тех пор, пока не выполнит ее acciГіn партнер .

нет Гєltimo точка из-за того, что сталкивается, чтобы иметь одну visiГіn обще:

Событий

- абстрактных существ , манипулируемые внутри из-за intГ©rprete. Они могут происходить от различных шрифтов: Операционная система (ratГіn, клавиатура, переизмерение окна...), часы (использованные, чтобы осуществлять setInterval( ) и setTimeout( ), произведенные внутри самим intГ©rprete (DOMContentLoaded...), и(или) любой другой шрифт.

В действительности, не имеет значения для нас, как они были осуществлены, и quiГ©n я произвел их. Нашей Гєnica opciГіn производить и отвечать им . В этом Гєltimo я вступаю в брак, это пистолетный выстрел вывода , нашпигуй для нее ejecuciГіn нашего cГіdigo. Давайте помнить, что, как было сказано сначала, el estado natural del intérprete es no hacer nada.

Изображение обобщают:

introducir la descripción de la imagen aquí

Восток смоделировал, основанный на событии и реакциях на них, он очень, очень comГєn в ней programaciГіn сред grГЎficos, в практически любых язык.

TambiГ©n, эта модель представляет недостаток: обвиняемый событий останавливает до тех пор, пока не заканчивает ее ejecuciГіn cГіdigo язык сценариев JavaScript в настоящее время текущий. Это мотив разубеждать использование функций sГ-ncronas : браузер ничего не может делать (кроме продолжения сохранять события в очереди) пока estГЎ выполняя cГіdigo язык сценариев JavaScript. И, так как выражение cГіdigo estГЎ ожидая возврата с одной funciГіn sГ-ncrona , не podrГЎ заканчиваться до тех пор, пока он не получит результат этой funciГіn. Результат: браузер блокирует

Взамен, используются очень мало ресурсов во временах бездействия (что serГЎn mayorГ - в), и удали проблемы конкурирующего доступа к разделенным данным: не существует концепция hilos, и безопасный , что 2 функции не ejecutarГЎn одновременно.

язык сценариев JavaScript SГ-ncrono

Con увиденное ранее, мы прибываем в нее conclusiГіn из, что язык сценариев JavaScript - язык полностью asГ-ncrono или пассивные : не возможно ждать до тех пор, пока он не переместит что-то, но это что-то, когда пропуск, мы avisarГЎ.

Существуют, тем не менее, какие-то исключения. Более просторно известная: просьбы XMLHttpRequest sГ-ncronas.

Операционные системы обычно предоставляют 2 формы доступа к сети: sГ-ncronas и asГ-ncronas. В первой форме, программа делает одну peticiГіn и уполномочивает в Операционной системе до тех пор, пока эта не осуществляется. В течение этого времени, программы остается , спавшие . Операционная система помечает как в резерве , и не теряет время с Г©l до тех пор, пока из-за законченная запрос. В этом моменте, он это помечает как я заношу в список и продолжи Ваш ejecuciГіn.

Это имеет смысл в каких-то типах программ, которым, просто, ничего не нужно сделать до тех пор, пока не будет завершена какая-то acciГіn. Пометив как в резерве , Операционная система оптимизирует ресурсы, предоставляя больше времени в оставшуюся часть программ.

Этот способ работать - злосчастные в языке сценариев JavaScript. versiГіn sГ-ncrona XMLHttpRequest, действительно, блокирует полностью она pestaГ±a настоящая, включенная она gestiГіn событий. В эффекты prГЎcticos, она pestaГ±a остается , умершие до тех пор, пока не будет завершена она operaciГіn.

versiГіn sГ-ncrona XMLHttpRequest должен предотвращать во что бы то ни стало ; действительно, в ВЕБ приложениях, нет ningГєn мотива , чтобы использовать ее.

Возвращаясь в вопрос

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

мы Можем использовать одну aproximaciГіn классические :

function obtenerLosDatos( url, callback ) {
  var xhr = new XMLHttpRequest( );

  // Establecemos la REACCIÓN cuando cambie el estado de la solicitud.
  xhr.onreadystatechange( stateChanged );

  // Lanzamos la ACCIÓN.
  xhr.open( 'GET', url );
  xhr.send( );

  // REACCIÓN
  function stateChanged( ) {
    try {
      if( xhr.readyState == 4 ) callback( xhr.state, JSON.parse( xhr.responseText ) );
    } catch( err ) {
      callback( xhr.state, undefined );
    }
  }
}

function PedirDatosYHacerAlgo( ) {
  var url = 'http://example.com/data.json';

  obtenerLosDatos( url, funcionReaccion );

  function funcionReaccion( state, jsonData ) {
    // Recibimos el estado, por lo que podemos comprobar posibles errores.
    if( state != 200 ) {
      alert( 'ERROR !!' );
      return;
    }

    // Comprobamos el JSON recibido.
    if( jsonData === undefined ) {
      alert( 'BAD JSON' );
      return;
    }

    // Aquí tratamos los datos y hacemos lo que tengamos que hacer con ellos.
    ...
  }
}

специальных Случая

Как мы сказали, браузер остается блокированным пока работает наше cГіdigo язык сценариев JavaScript; перед этим, помещается возможность того, чтобы, в неких случаях, мы были должны реализовывать процессы, которые опаздывали бы много времени, способствуя тому, чтобы, накануне пользователя, наша aplicaciГіn остался разоренным . Следующий cГіdigo блокирует полностью она pesataГ±a включает в течение некоторого времени:

function ProcesoMuyLargo( ) {
  for( let idx = 0; idx < Number.MAX_SAFE_INTEGER; ++idx );
}

ProcesoMuyLargo( );

Для этих случаев, язык сценариев JavaScript предоставляет одну нам очень Гєtil funciГіn: setTimeout( ).

setTimeout( exp, time ):
EvalГєa она expresiГіn exp, перемещенные определенный nГєmero миллисекунд.

прием состоит в том, чтобы перемещать в time стоимость 0. Это размещает событие в конце очереди событий . А именно, браузер обрабатывает незаконченные события и, когда он прибудет к нашему, мы devolverГЎ она ejecuciГіn . Это могут использовать для оставлять ее pestaГ±a воспринимающая, хотя мы будем в очень длинных процессах :

function ProcesoMuyLargo( ) {
  var idx = 0;

  function Subproceso( ) {
    for( ; idx < Number.MAX_SAFE_INTEGER; ++idx ) {
      if( !( idx % 10000 ) ) {
        setTimeout( Subproceso, 0 );
        return;
      }
    }
  }
}

ProcesoMuyLargo( );

nГєmero использованный, 10000, полностью произвольный. Больше, меньше tardarГЎ цикл в заканчивании, но браузер volverГЎ больше бродил в действия пользователя. Больше pequeГ±o, браузер отвечает раньше на действия, но цикл tardarГЎ больше в том, чтобы быть завершенным.

9
ответ дан 03.12.2019, 04:09
  • 1
    Нет из-за añ adir касающееся async / await. Я не очень приучен для этого... даже :-) –  Trauma 05.03.2019, 21:34
  • 2
    async и await он má s azú car sintá ctico для обещаний –  Pablo Lozano 06.03.2019, 13:10
  • 3
    @PabloLozano я не так уверен... Я сделал мои доказательства, и то, что я наблюдал, не могут воспроизводить только с обещаниями... Или я не способен, по крайней мере O_O –  Trauma 06.03.2019, 13:23