Есть ли способ выполнить синхронный запрос AJAX, который не блокирует браузер? На мой взгляд, синхронные запросы в большинстве случаев намного легче работать, но тот факт, что они блокируют выполнение других частей кода, является настоящим убийцей. Есть ли способ получить синхронный AJAX без отрицательных побочных эффектов? (И да, я понимаю, что термин «Синхронный AJAX» является оксюмороном.)Неблокирующий синхронный AJAX
ответ
Я приведу пример плохой стороны воздействия такого поведения.
Допустим, у вас есть эта программа:
<script>
var file = "foo.json";
function nullIt() {
file = null;
}
function loadFile() {
if (file != null) {
synchronousLoad(file);//imagine the load takes 5 seconds
alert("i just loaded: " + file);
}
}
window.onload = loadFile;
</script>
<button onclick="nullIt()">click me</button>
Плохая вещь здесь-
- а
synchronousLoad()
блокирует в течение 5 секунд, когда пользователь нажимает на кнопку, и обработчик события быстро разряжается до завершения. - Теперь переменная
file
равна нулю. synchronousLoad()
заканчивается и возвращается, выпускающие выполнения резюме на следующей строке кода- но
file
теперь нуль, и выдает сообщение пользователю сломана.
Настоящая проблема здесь вы больше не можете рассуждать о своем коде. Просто потому, что какой-то факт был true в строке 5, не означает, что он по-прежнему верен на самой следующей строке. Это затрудняет запись бесплатной программы.
Некоторые языки программирования поддерживают многопоточность, и вам приходится иметь дело с этими проблемами, хотя у вас есть инструменты для решения этих проблем. Но это еще много дополнительных усилий для части программистов.
Сравнительно говоря, использование обратных вызовов для выполнения асинхронных операций - это ez-режим.
Ах, отличная точка. Лично я бы предпочел рискнуть с такими «условиями гонки» (если можно так выразиться), но приятно видеть какое-то оправдание, почему все так, как есть. – Ajedi32
№ Синхронный по определению блокирует. Ничто не может продолжаться до тех пор, пока процесс не завершится. Это включает в себя остальную часть пользовательского интерфейса в веб-браузере.
Это Предполагается, что будет асинхронным, поэтому наилучшим подходом является разработка кода для работы асинхронно.
Я не думаю, что это возможно. Вместо того, чтобы пытаться использовать синхронные запросы, вы можете использовать асинхронный подход и использовать событие AJAX done.
Пример использования jQuery.ajax()
jQuery.ajax({
url: "URL HERE",
data: "whatever you are sending"
}).done(function (data) {
// Do things with data
});
Таким образом, вместо того, чтобы использовать синхронный запрос, вы можете использовать запрос Asynchronous и просто выполнить код после того, как запрос завершен. Таким образом, он не будет замораживать ваш браузер.
Да, но это именно то, чего я пытаюсь избежать, выполняя синхронный запрос. В текущем пути выполнения моего кода нет ничего, что должно быть выполнено до тех пор, пока запрос не будет завершен, поэтому кажется, что чистнее просто выполнять синхронный запрос. Я просто не хочу, чтобы он блокировал другие части моего кода, пока он ждет. – Ajedi32
@ Ajedi32 Это совсем не чище - в частности, потому что он * не работает * с одним контекстом выполнения, например, используемым браузером JavaScript. Кроме того, когда используются несколько контекстов выполнения (т. Е. Потоки или даже продолжения), есть дополнительные соображения и проблемы, связанные с: неявное атомное исполнение удаляется, и [другие формы] условий гонки должны быть защищены. – user2246674
@ Ajedi32 Используя обещания (в частности, 'then', реализованные в jQuery 1.8+ и кодированные [Promises/A] (http://wiki.commonjs.org/wiki/Promises/A)), могут значительно очистить асинхронный код Применение. Я считаю, что эта модель обещаний намного более последовательна и чиста для решения, чем предыдущие обратные вызовы/ошибки. – user2246674
По причинам, изложенным в других ответах здесь, нет возможности выполнить синхронный вызов AJAX без блокировки других событий в браузере.
Однако, если сложность кода является основной причиной нежелания асинхронных вызовов методов, вам может быть интересен кросс-компилятор Javascript streamline.js, который позволяет вам писать асинхронные вызовы методов, как если бы они были синхронными, и получить такой же результат, как если бы вы написали вызов асинхронно.
С GitHub страницы проекта:
streamline.js является инструментом языка для упрощения асинхронного Javascript программирования.
Вместо того чтобы писать код волосатые, как:
function archiveOrders(date, cb) { db.connect(function(err, conn) { if (err) return cb(err); conn.query("select * from orders where date < ?", [date], function(err, orders) { if (err) return cb(err); helper.each(orders, function(order, next) { conn.execute("insert into archivedOrders ...", [order.id, ...], function(err) { if (err) return cb(err); conn.execute("delete from orders where id=?", [order.id], function(err) { if (err) return cb(err); next(); }); }); }, function() { console.log("orders have been archived"); cb(); }); }); }); }
Вы пишете:
function archiveOrders(date, _) { var conn = db.connect(_); conn.query("select * from orders where date < ?", [date], _).forEach_(_, function(_, order) { conn.execute("insert into archivedOrders ...", [order.id, ...], _); conn.execute("delete from orders where id=?", [order.id], _); }); console.log("orders have been archived"); }
и обтекаемый преобразует код и заботится о обратных вызовов!
Нет API-интерфейсов управления доступом, чтобы узнать! Вы просто должны следовать простому правилу:
Заменить все обратные вызовы подчеркивания и писать код, как если бы все функций были синхронны.
Для получения дополнительной информации о streamline.js, читайте в нашем блоге Asynchronous Javascript – the tale of Harry.
В новом стандарте ECMAScript 2016 (ES7) есть новый набор языковых ключевых слов, предназначенный для выполнения чего-то очень похожего на то, что вы, похоже, ищете, называется async
и await
.
Эти ключевые слова не позволяют «неблокирующая синхронную AJAX», но они не позволяют писать асинхронный код таким образом, что выглядит синхронными. Вот простой пример:
// Let's say you have an asynchronous function that you want to call in a synchronous
// style...
function delayedEval(delay, func) {
// First, ensure that the function returns a Promise object. If it doesn't, wrap it with
// another function that does.
return new Promise((resolve, reject) => {
setTimeout(() => resolve(func()), delay)
})
// For more on Promises, see https://goo.gl/uaoDuy (MDN link)
}
// Then, declare a function as asynchronous. This causes it to return a Promise that
// resolves to its return value, instead of returning its return value directly.
async function delayedHello() {
// Inside an async function, you can call other async functions like this, which looks
// very much like a synchronous call (even though it isn't).
let message = await delayedEval(1500,() => "Hello, world!")
console.log(message)
}
// This returns (a Promise) immediately, but doesn't print "Hello, world!" until 1.5
// seconds later. (At which point it resolves the Promise.)
delayedHello()
В принципе, вместо «синхронизирован AJAX без негативных побочных эффектов», async
и await
получить вам асинхронный AJAX без всех его негативных побочных эффектов. (Мессиальный код с большим количеством логики для обработки обратных вызовов.)
async
и await
являются частью "async functions" candidate recommendation в стандарте ES7.
- 1. Синхронный Ajax
- 2. Синхронный вызов AJAX не по-настоящему синхронный
- 3. Реальный синхронный вызов ajax
- 4. Синхронный вызов AJAX
- 5. Синхронный JQuery Ajax Call
- 6. Синхронный Ajax с jQuery
- 7. Синхронный AJAX (сломанные обещания)
- 8. Синхронный Ajax: Гарантированный последовательный?
- 9. nodejs - это асинхронный/синхронный процесс, неблокирующий/блокирующий IO
- 10. Поддерживает ли синхронный запрос синхронный синхронный запрос?
- 11. ajax синхронный вызов с таймаутом
- 12. Синхронный ajax в сервере node.js
- 13. Синхронный Ajax-запрос «блокировка» браузера
- 14. JQuery правильно Синхронный Ajax вызов
- 15. Javascript синхронный тайм-аут AJAX
- 16. сделать синхронный в AJAX-код
- 17. JavaScript синхронный запрос Ajax Idodayncrasies
- 18. Синхронный запрос AJAX с JSONP
- 19. ExtJs Ajax запрос исключение синхронный
- 20. Синхронный тайм-аут Ajax в webview
- 21. Как работает синхронный AJAX-запрос jQuery?
- 22. jQuery ajax вызов синхронный и асинхронный?
- 23. синхронный jquery $ .ajax без блокировки IE?
- 24. Zombie.js не выполняет синхронный AJAX-запросы
- 25. Синхронный AJAX (SJAX) при восстановлении сеанса
- 26. window.onbeforeunload, закрывающий браузер и синхронный AJAX
- 27. Асинхронный и синхронный XMLHttpRequest в ajax
- 28. Когда это целесообразно использовать синхронный ajax?
- 29. Синхронный вызов «Ajax» с JQuery не работает
- 30. синхронный jquery ajax звонок в magento
Я так не думаю ... Предлагаю вам узнать о обещаниях, облегчить работу с AJAX. – elclanrs
@hexacyanide Извините, я думаю, это было плохо сформулировано. Я имею в виду, что он не замораживает браузер или блокирует другие события в моем коде от запуска. – Ajedi32
Даже если «неблокирующее синхронное» не было противоречием, это невозможно для такой конструкции в однопотоковой (однопоточной) среде. Альтернативой и, действительно, решением в браузере JavaScript является «неблокирующее * асинхронное». – user2246674