Я хотел бы предисловие к этому с извинениями, если я делаю вещи «странным» способом, так как я в первую очередь разработчик C и решаю эту проблему AJAX так, C.JavaScript синхронный запрос Ajax Idodayncrasies
У меня есть сценарий, который будет подключаться к «push-серверу», который ждет, пока сообщение будет доступно, затем отправит только одно сообщение и разрывает соединение. Затем клиент должен восстановить соединение для прослушивания будущих сообщений.
Я пытался сделать это путем реализации синхронной AJAX вызова в пределах асинхронного обратного вызова, и она работает за исключением того, появляется DOM (может быть? Я показываю свое невежество JS здесь) не будет блокировать до все звонки завершены.
Я не знаю, как это сделать с чисто асинхронными вызовами, поскольку я не хочу в конечном итоге исчерпать стек, обратившись обратным вызовом каждый раз.
Это код:
$.ajax({
url: './recoverDevice',
data: JSON.stringify(requestData),
dataType: 'json',
type: 'POST',
success: function(j)
{
console.log(j);
if (j.success)
{
//Indefinitely listen for push messages from the server
var loopMore = true;
while(loopMore)
{
$.ajax({
async: false,
url: './getPendingMessage',
dataType: 'json',
type: 'POST',
success: function(j)
{
//alert(j.message);
$("#progressBox").append("<li>" + j.message + "</li>");
loopMore = !j.complete;
}
});
}
}
else
{
$("#errorBox").show();
$("#errorBox").text(j.errorMessage);
}
}
});
Теперь, по логике вещей, этот код должен работы. Внутри функции asynchronous, я петлю через синхронный JS-вызов, каждый раз, когда я получаю сообщение, я добавлю его в DOM, и только когда сервер скажет мне, что больше не будет сообщений, я выхожу из цикла, завершение асинхронного потока и завершение задачи.
Проблема в том, что доступ DOM, кажется, был объединен один раз все сообщения были получены. то есть добавление происходит только после того, как все сообщения были получены, и асинхронный поток вышел из него.
Прокомментировал alert
был тест - он работает отлично. Я получаю окно сообщения после каждого уведомления, и он делает паузу корректно до следующего сообщения (с остальной частью кода как есть).
Я предполагаю, что это мой браузер (Chrome), делающий магию для защиты от условий гонки, не допуская манипуляции DOM до выхода асинхронной нити? Или я нахожусь в стороне от знака и лаем здесь неправильное дерево?
Избавление от цикла и установка async
на значение true, чтобы первое сообщение принималось должным образом (никаких проблем там нет), но, очевидно, после этого сообщений нет.
Очевидно, что я мог бы сделать что-то вроде этого:
function GetMessage()
{
$.ajax({
async: true,
url: './getPendingMessage',
dataType: 'json',
type: 'POST',
success: function(j)
{
$("#progressBox").append("<li>" + j.message + "</li>");
if (!j.complete)
{
GetMessage();
}
}
});
}
Но это приведет к переполнению стека с течением времени (нет?).
Очевидным решением было бы использовать асинхронные вызовы здесь, но чтобы сигнализировать цикл while для приостановки и продолжения новых вызовов через какие-то примитивы синхронизации, но похоже, что у JS нет сигнальных примитивов?
Причина, по которой первый метод «не работал», был просто функцией алгоритма перерисовки браузера. Однопоточный синхронный js блокируется, так что, пока поток обрабатывается, браузер не перерисовывает. Однако он перерисовывается, когда появляется окно предупреждения (код по-прежнему синхронный и в некотором смысле блокирующий, но под капотом я полагаю, что он имеет ожидающее/неблокирующее состояние в том, что касается алгоритма перерисовывания), поэтому он предположительно выглядел нормально с предупреждением. Просто нюансы реализации. – davin
Но синхронный js-код вызывался из уже асинхронного потока js ..? –
Это не имеет значения, я не уверен, почему вы так думаете. «Асинхронная нить» на самом деле не имеет большого значения. Когда кусок кода возвращается в цикл событий, он неотличим от любого другого фрагмента кода, поэтому независимо от того, началось ли его выполнение синхронно или нет, текущее выполнение является синхронным. Это похоже на людей, прибывающих на вечеринку, хотя некоторые люди ходят, а другие приходят на машине (синхронно или асинхронно, по общему признанию, не самая лучшая аналогия), как только они приходят, они проверяются по безопасности один за другим. – davin