Асинхронное программирование в JavaScript без грязных обратных вызовов

Я хочу повернуть асинхронную функцию к синхронному.

function fetch() {
  var result = 'snap!';
  $.getJSON("http://api.flickr.com/services/feeds/photos_public.gne?tags=cat&tagmode=any&format=json&jsoncallback=?", function messyCallback(data){
    result = data;
  });
  return result;
}

document.write(fetch());​

Посмотрите в действии

Результатом всегда будет 'снимок!', потому что $.getJSON бежать fetch() сделан.

Моя первая идея была:

function fetch() {
  var result = 'snap!';
  $.getJSON("http://api.flickr.com/services/feeds/photos_public.gne?tags=cat&tagmode=any&format=json&jsoncallback=?", function messyCallback(data){
    result = data;
  });
  while (true) {
    if (result != 'snap!') return result;
  }
}

Это не работает и также сдувает браузер.

Я читал о генераторах и итераторах в JS 1.7, но я понятия не имею, как применить его к моей проблеме.

Этот вопрос не действительно о jQuery. Вместо $ .getJSON мог быть любой другой асинхронной функцией.

7
задан NVI 8 February 2010 в 16:38
поделиться

4 ответа

Вы хотите использовать собственный $ .getSyncJSON, который использует $ .ajax ({async: false}). См .: http://api.jquery.com/jQuery.ajax/ .

Однако я должен посоветовать вам не делать этого. Вы можете легко заблокировать браузер от любого ввода, отдав свой пользовательский интерфейс на откуп сети. Но если вы знаете, что делаете, и уверены в своем варианте использования, дерзайте.

2
ответ дан 6 December 2019 в 10:50
поделиться

Более низкоуровневая функция $.ajax() из jQuery имеет больше опций, включая async: [true|false] (по умолчанию true).

Тем не менее, в большинстве случаев вы должны следовать совету Бена и "принять асинхронную природу языка".

1
ответ дан 6 December 2019 в 10:50
поделиться

Вместо того, чтобы писать вспомогательные методы, такие как ваш fetch , которые возвращают значение, заставьте их принимать другую функцию, «получатель», чтобы передать свой результат в:

function fetch(receiver) {

    $.getJSON("blah...", function(data) {

        receiver(data);
    });
}

Очевидно, это избыточно, потому что именно так getJSON уже работает, но в более реалистичном примере функция fetch каким-то образом обработает или отфильтрует результат перед его передачей.

Тогда вместо:

document.write(fetch());​

Вы бы сделали:

fetch(function(result) { document.write(result); });

Генераторы можно использовать, чтобы сделать асинхронный код более линейным по стилю. Каждый раз, когда вам нужен был какой-то асинхронный результат, вы выдавали функцию для его запуска, и генератор возобновлял работу, когда результат был доступен. Для работы генератора потребуется немного кода управления. Но это не очень помогает, потому что генераторы не являются стандартными для браузеров.

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

2
ответ дан 6 December 2019 в 10:50
поделиться

Я считаю, что важно то, что каждый связанный со строками репозиторий/база данных может иметь свои собственные характеристики, которыми можно манипулировать или использовать для создания оптимальных функций последовательности. Однако в этом посте есть несколько легких трюков для некоторых случаев - вы можете выбрать, что подходит под ваши потребности и использовать его: http://www.codemaestro.com/articles/21

-121--4540783-

Да его раздражает. Вы можете использовать strdup для его сокращения:

char *p = strdup("hello");
printf("p is %s \n",p);
-121--4557578-

См. также вопрос: Остановить выполнение JavaScript без блокировки браузера

Делать именно то, что вы хотите, не работает. Нельзя создавать синхронность из асинхронности (только другие пути вокруг!) в однопоточной среде, управляемой событиями. Вы должны принять асинхронный характер языка и разработать свой собственный согласованный стиль обработки обратных вызовов, чтобы ваш код был читаемым/поддерживаемым. Можно, например, выбрать, чтобы никогда не выполнять реальную работу внутри закрытия обратного вызова, а просто вызвать другую функцию/метод верхнего уровня для ясности.

9
ответ дан 6 December 2019 в 10:50
поделиться
Другие вопросы по тегам:

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