Я хочу повернуть асинхронную функцию к синхронному.
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 мог быть любой другой асинхронной функцией.
Вы хотите использовать собственный $ .getSyncJSON, который использует $ .ajax ({async: false}). См .: http://api.jquery.com/jQuery.ajax/ .
Однако я должен посоветовать вам не делать этого. Вы можете легко заблокировать браузер от любого ввода, отдав свой пользовательский интерфейс на откуп сети. Но если вы знаете, что делаете, и уверены в своем варианте использования, дерзайте.
Более низкоуровневая функция $.ajax() из jQuery имеет больше опций, включая async: [true|false]
(по умолчанию true).
Тем не менее, в большинстве случаев вы должны следовать совету Бена и "принять асинхронную природу языка".
Вместо того, чтобы писать вспомогательные методы, такие как ваш fetch
, которые возвращают значение, заставьте их принимать другую функцию, «получатель», чтобы передать свой результат в:
function fetch(receiver) {
$.getJSON("blah...", function(data) {
receiver(data);
});
}
Очевидно, это избыточно, потому что именно так getJSON
уже работает, но в более реалистичном примере функция fetch
каким-то образом обработает или отфильтрует результат перед его передачей.
Тогда вместо:
document.write(fetch());
Вы бы сделали:
fetch(function(result) { document.write(result); });
Генераторы можно использовать, чтобы сделать асинхронный код более линейным по стилю. Каждый раз, когда вам нужен был какой-то асинхронный результат, вы выдавали функцию для его запуска, и генератор возобновлял работу, когда результат был доступен. Для работы генератора потребуется немного кода управления. Но это не очень помогает, потому что генераторы не являются стандартными для браузеров.
Если вам интересно, вот сообщение в блоге об использовании генераторов для очистки асинхронного кода .
Я считаю, что важно то, что каждый связанный со строками репозиторий/база данных может иметь свои собственные характеристики, которыми можно манипулировать или использовать для создания оптимальных функций последовательности. Однако в этом посте есть несколько легких трюков для некоторых случаев - вы можете выбрать, что подходит под ваши потребности и использовать его: http://www.codemaestro.com/articles/21
-121--4540783- Да его раздражает. Вы можете использовать strdup
для его сокращения:
char *p = strdup("hello");
printf("p is %s \n",p);
-121--4557578- См. также вопрос: Остановить выполнение JavaScript без блокировки браузера
Делать именно то, что вы хотите, не работает. Нельзя создавать синхронность из асинхронности (только другие пути вокруг!) в однопоточной среде, управляемой событиями. Вы должны принять асинхронный характер языка и разработать свой собственный согласованный стиль обработки обратных вызовов, чтобы ваш код был читаемым/поддерживаемым. Можно, например, выбрать, чтобы никогда не выполнять реальную работу внутри закрытия обратного вызова, а просто вызвать другую функцию/метод верхнего уровня для ясности.