Вы будете заботиться, является ли Ваш профиль пользователя несколькими устаревшими секундами?
Нет - это совершенно приемлемо. Установка основного уровня изоляции транзакции является, вероятно, лучшим/самым чистым способом пойти.
$. GetJSON
является асинхронным. То есть код после вызова выполняется, пока $. GetJSON
извлекает и анализирует данные и вызывает ваш обратный вызов.
Итак, учитывая следующее:
a();
$.getJSON("url", function() {
b();
});
c();
Порядок вызовов a
, b
и c
могут быть либо abc
(что вы хотите в данном случае), либо acb
(более вероятно, что это действительно произойдет).
Решение?
Сделайте запрос синхронным вместо асинхронного:
a();
$.ajax({
async: false,
url: "url",
success: function() {
b();
}
});
c();
Переместите вызов на c
после вызова b
:
a();
$.getJSON("url", function() {
b();
c();
});
«Но это делается посредством последующих взаимодействий на странице, и я не могу предвидеть, что пользователь захочет делать с объектом JSON в обратном вызове».
Обратный вызов - это ваша возможность чтобы настроить экран для взаимодействия пользователя с данными.
Вы можете создать или раскрыть HTML для пользователя и настроить больше обратных вызовов.
В большинстве случаев ни один из ваших кодов не будет запущен. Программирование страницы Ajax - это размышление о том, какие события и когда могут произойти.
Есть причина, по которой это «Ajax», а не «Sjax». Есть причина, по которой сложно переходить с асинхронной на синхронизацию. Ожидается, что вы сделаете страницу асинхронной.
Программирование, управляемое событиями, может сначала расстраивать.
Я выполнил ресурсоемкие финансовые алгоритмы на JS. Даже тогда это ' То же самое - вы разбиваете его на маленькие части, а события - это тайм-ауты.
Анимация в JavaScript также управляется событиями. Фактически, браузер даже не покажет движение, если ваш скрипт повторно не откажется от управления.
Вы просто столкнулись с проблемами определения объема.
Краткий ответ:
window.jsonIssues = {}; // or tack on to some other accessible var
$.getJSON("url", function(data) {
window.jsonIssues = data.Issues;
});
// see results here
alert(window.jsonIssues);
Длинные ответы:
Проблема с ограничением области видимости в Javascript Проблема с ограничением области действия Javascript
Помните, что когда вы предоставляете функцию обратного вызова, суть этого заключается в том, чтобы отложить выполнение этого обратного вызова на более позднее время и немедленно продолжить выполнение всего, что будет следующим. Это необходимо из-за однопоточной модели выполнения JavaScript в браузере. Возможно принудительное синхронное выполнение, но при этом браузер зависает на все время выполнения операции. В случае чего-то вроде $ .getJSON это недопустимо долгое время для того, чтобы браузер перестал отвечать.
Другими словами, вы пытаетесь найти способ использовать эту процедурную парадигму:
var foo = {};
$.getJSON("url", function(data) {
foo = data.property;
});
// Use foo here.
Когда вам нужно для рефакторинга кода, чтобы он выглядел примерно так:
$.getJSON("url", function(data) {
// Do something with data.property here.
});
«Сделай что-нибудь» может быть вызовом другой функции, если вы хотите, чтобы функция обратного вызова оставалась простой. Важно то, что вы ждете до $. getJSON завершается перед выполнением кода.
Вы даже можете использовать настраиваемые события, чтобы код, который вы разместили после $ .getJSON, подписывался на событие IssuesReceived, и вы вызывали это событие в обратном вызове $ .getJSON:
$(document).ready(function() {
$(document).bind('IssuesReceived', IssuesReceived)
$.getJSON("url", function(data) {
$(document).trigger('IssuesReceived', data);
});
});
function IssuesReceived(evt, data) {
// Do something with data here.
}
Обновление:
Или вы можете хранить данные глобально и просто использовать настраиваемое событие для уведомления о том, что данные были получены и глобальная переменная обновлена.
$(document).ready(function() {
$(document).bind('IssuesReceived', IssuesReceived)
$.getJSON("url", function(data) {
// I prefer the window.data syntax so that it's obvious
// that the variable is global.
window.data = data;
$(document).trigger('IssuesReceived');
});
});
function IssuesReceived(evt) {
// Do something with window.data here.
// (e.g. create the drag 'n drop interface)
}
// Wired up as the "drop" callback handler on
// your drag 'n drop UI.
function OnDrop(evt) {
// Modify window.data accordingly.
}
// Maybe wired up as the click handler for a
// "Save changes" button.
function SaveChanges() {
$.post("SaveUrl", window.data);
}
Обновление 2:
В ответ на это:
Есть ли у кого-нибудь идея, как я должен блокировать взаимодействие с пользователем, пока это происходит? Почему это вызывает такое беспокойство? Еще раз спасибо за все ответы.
Причина, по которой вам следует избегать блокировки браузера с помощью синхронных вызовов AJAX, заключается в том, что заблокированный поток JavaScript также блокирует все остальное в браузере , включая другие вкладки и даже другие окна . Это означает отсутствие прокрутки, навигации, Нет, ничего. Для всех намерений и целей это выглядит так, как если бы произошел сбой браузера. Как вы понимаете, страница, которая ведет себя подобным образом, является значительной помехой для пользователей.