(Да, есть условие гонки.)
Адресация Только JavaScript
Весь код JavaScript на странице (кроме веб-работников), который включает в себя обратные вызовы, выполняется "взаимно"exclusive ".
В этом случае, поскольку newInfoItems оценивается с нетерпением , он даже не настолько сложен: и" / api / news / 0 ", и" / api / news / 1 "гарантированно будут выбраны (или потерпят неудачу при попытке).Сравните это с:
// eager evaluation: value of url computed BEFORE request
// this is same as in example (with "fixed" increment order ;-)
// and is just to show point
var url = "/api/news/" + this.newInfoItems
this.newInfoItems += 1;
jQuery.get(url,
function(html) {
// only evaluated on AJAX callback - order of callbacks
// not defined, but will still be mutually exclusive.
jQuery('div.col'+side).append(html);
}
);
Однако порядок , в котором завершаются запросы AJAX, не определен и зависит от сервера и браузера.Кроме того, как обсуждается ниже, не существует атомарного контекста, установленного между сервером и отдельными AJAX-запросами .
Обращение к JavaScript в контексте
Теперь, даже если установлено, что"/ api / news / 0" и"/ api / news / 1" будут вызваны, представьте себе, что маловероятно, но теоретически возможно ситуация:
- статьи
B,A
существуют в базе данных - браузер отправляет оба AJAX-запроса - асинхронно или синхронно, это не имеет значения!
- статья добавлена в базу данныхиногда между , когда
- сервер обрабатывает запрос
news/0
, а - сервер обрабатывает
news/1
запрос
Затем это происходит:
news/0
возвращает статью B
(статьи B,A
в базе данных) - статья
C
добавлено news/1
возвращает статью B
(статьи C,B,A
в базе данных)
Обратите внимание, что статья B
была возвращена дважды !Упс:)
Итак, хотя состояние гонки "кажется маловероятным" , оно существует.Подобное состояние гонки (с другими результатами) может возникнуть, если news/1
обработано до news/0
и (еще раз) добавлена статья между запросами: нет атомарной гарантии в любом случае!
(Приведенное выше условие гонки будет более вероятным , если выполнение запросов AJAX последовательно, поскольку время для добавления новой статьи увеличивается.)
Возможное решение
Подумайте, скажем, о n
(2 все в порядке!) Статей в одном запросе (например, "/ api / latest / n"), а затем выложитесоответствующие статьи в обратном вызове .Например, первая половина статей слева и вторая половина справа, или что-то подходящее.
А также устранение вышеупомянутого конкретного состояния расы, делая единственный запрос атомарным действием -Что касается добавления статей - это также приведет к уменьшению сетевого трафика и уменьшению работы сервера.
Выборка для API может выглядеть следующим образом:
SELECT *
FROM news
ORDER BY `date` DESC
LIMIT :n
Счастливое кодирование.