Набор переменных во время $ .getJSON функционирует только доступный в функции

Вы будете заботиться, является ли Ваш профиль пользователя несколькими устаревшими секундами?

Нет - это совершенно приемлемо. Установка основного уровня изоляции транзакции является, вероятно, лучшим/самым чистым способом пойти.

44
задан MegaMatt 16 November 2009 в 04:07
поделиться

4 ответа

$. GetJSON является асинхронным. То есть код после вызова выполняется, пока $. GetJSON извлекает и анализирует данные и вызывает ваш обратный вызов.

Итак, учитывая следующее:

a();

$.getJSON("url", function() {
    b();
});

c();

Порядок вызовов a , b и c могут быть либо abc (что вы хотите в данном случае), либо acb (более вероятно, что это действительно произойдет).

Решение?

Синхронные запросы XHR

Сделайте запрос синхронным вместо асинхронного:

a();

$.ajax({
    async: false,
    url: "url",
    success: function() {
        b();
    }
});

c();

Код реструктуризации

Переместите вызов на c после вызова b :

a();

$.getJSON("url", function() {
    b();

    c();
});
34
ответ дан 26 November 2019 в 22:18
поделиться

«Но это делается посредством последующих взаимодействий на странице, и я не могу предвидеть, что пользователь захочет делать с объектом JSON в обратном вызове».

Обратный вызов - это ваша возможность чтобы настроить экран для взаимодействия пользователя с данными.

Вы можете создать или раскрыть HTML для пользователя и настроить больше обратных вызовов.

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

Есть причина, по которой это «Ajax», а не «Sjax». Есть причина, по которой сложно переходить с асинхронной на синхронизацию. Ожидается, что вы сделаете страницу асинхронной.

Программирование, управляемое событиями, может сначала расстраивать.

Я выполнил ресурсоемкие финансовые алгоритмы на JS. Даже тогда это ' То же самое - вы разбиваете его на маленькие части, а события - это тайм-ауты.

Анимация в JavaScript также управляется событиями. Фактически, браузер даже не покажет движение, если ваш скрипт повторно не откажется от управления.

1
ответ дан 26 November 2019 в 22:18
поделиться

Вы просто столкнулись с проблемами определения объема.

Краткий ответ:

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

-3
ответ дан 26 November 2019 в 22:18
поделиться

Помните, что когда вы предоставляете функцию обратного вызова, суть этого заключается в том, чтобы отложить выполнение этого обратного вызова на более позднее время и немедленно продолжить выполнение всего, что будет следующим. Это необходимо из-за однопоточной модели выполнения 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 также блокирует все остальное в браузере , включая другие вкладки и даже другие окна . Это означает отсутствие прокрутки, навигации, Нет, ничего. Для всех намерений и целей это выглядит так, как если бы произошел сбой браузера. Как вы понимаете, страница, которая ведет себя подобным образом, является значительной помехой для пользователей.

9
ответ дан 26 November 2019 в 22:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: