Несоответствия API или JavaScript
У меня есть JS функция в моем шаблоне, которая работает с командами fetch для передачи в представление Django. Странно то, что большую часть времени она работает так, как ожидается, но иногда она просто не работает, и я не могу понять, почему.
JS в шаблоне:
<script>
if (document.querySelectorAll(".nav-link")[1].innerHTML != "Log In") {
var like = document.querySelector(".likes");
var quantity = document.querySelector(".quantity");
like.addEventListener("click", () => likes())
function likes () {
fetch(`/likes/${like.value}`, {
method: "PUT"});
if (like.innerHTML.slice(0, 2) != "Un") {
like.innerHTML = "Unlike 💔";
}
else {
like.innerHTML = "Like ❤";
}
fetch(`/likes/${like.value}`)
.then(response => response.json())
.then(post => {
console.log(post["liked"]);
quantity.innerHTML = post["liked"].length;
});
}
}
</script>
Мое мнение:
@csrf_exempt
@login_required
def likes(request, id):
user = User.objects.get(username=request.user)
try:
post = Post.objects.get(pk=id)
except Post.DoesNotExist:
return JsonResponse({"error": "No such post"}, status=404)
if request.method == "GET":
return JsonResponse(post.serialize())
if request.method == "PUT":
#data = json.loads(request)
if user not in post.liked.all() and post.poster != user:
print("adding")
post.liked.add(user)
post.save()
else:
print("removing")
post.liked.remove(user)
post.save()
return HttpResponse(status=204)
Нужно чередовать пустой список и список, содержащий двойку.
Однако вы можете видеть, что, хотя обычно он работает правильно, в нем есть место, где есть несколько "[2]" подряд, а иногда и несколько "[]" подряд.
На самом деле это началось только после добавления второй выборки, но я не могу понять почему; до этого она чередовалась без проблем.
Как @Jared Smith
сказал в комментариях, нет гарантии порядка fetch
, так как он асинхронный, для контроля порядка используйте async
и await
для ожидания результата ответа, примерно так:
like.addEventListener("click", async () => await likes())
async function likes () {
await fetch(`/likes/${like.value}`, {
method: "PUT"});
if (like.innerHTML.slice(0, 2) != "Un") {
like.innerHTML = "Unlike 💔";
}
else {
like.innerHTML = "Like ❤";
}
await fetch(`/likes/${like.value}`);
const post = await response.json();
quantity.innerHTML = post["liked"].length;
}