RussianNinja
@RussianNinja

Как получить return из ajax запроса?

Всем, доброго времени суток. Есть следующее событие на клик:

$('.post-like').click(function(){
    var item_id = $(this).parents('.item').attr('id');
    var isVoted = false;
    //проверяем что пользователь уже проголосовал
    already_vote(item_id, isVoted);
    
    if(isVoted){
        //...
    }

    else{
        //...
    }
});


В функции already_vote() находится ajax запрос:

function already_vote(post_id, isVoted){
    $.ajax({
        url: '/ajax/post_like.php',
        type: 'POST',
        dataType: "json",
        data: {
            action: 'check',
            post_id: post_id
        },
    })
    .done(function(response){
        if(response.already_vote == 1){
            isVoted = true;
        }
    })
    .fail(function(xhr){
        console.log(xhr);
    });
}


Собственно нужно в событии click получить переменную isVoted. Простой return не работает, т.к. ajax асинхронный запрос. Знаю что можно просто использовать async: false, тогда работает как надо. Но эта фича считается устаревшей (о чем и сообщает консоль в браузере) и в перспективе может перестать работать. Нагуглил что правильно это делать через callback функции, но что-то не получается. Подскажите как нужно.
  • Вопрос задан
  • 114 просмотров
Решения вопроса 2
@StiflerProger
Всё верно тебе написали. Либо передавай callback в функцию already_vote, либо выполняй через промис.

Вариант с колбеком:
function already_vote(post_id, callback){
    $.ajax({ <options> })
    .done(function(response){
        if(response.already_vote == 1){
            return callback(true);
        }
        return callback(false);
    })
    .fail(function(xhr){
        console.log(xhr);
    });
}

$('.post-like').click(function(){
  const item_id = $(this).parents('.item').attr('id');

  already_vote(item_id, function(isVoted) {
    if(isVoted){
        //...
    }
    else {
        //...
    }
});
    
});


Вариант с промисом:
function already_vote(post_id, callback){
  return new Promise(res => {
    $.ajax({ <options> })
    .done(function(response){
        if(response.already_vote == 1){
            return res(true);
        }
        return res(false);
    })
  });
}

$('.post-like').click(async function(){
  const item_id = $(this).parents('.item').attr('id');

  const isVoted = await already_vote(item_id);
  
  if(isVoted){
        //...
  }
  else {
        //...
  }
    
});
Ответ написан
zkrvndm
@zkrvndm
Архитектор решений
Используйте async / await - это наиболее просто и удобный способ.

Пример:
$('.post-like').click(async function(){
	
	var response = await $.ajax({
		url: '/ajax/post_like.php',
		type: 'POST',
		dataType: 'json',
		data: {
			action: 'check',
			post_id: $(this).parents('.item').attr('id')
		}
	});
	
	if (response.already_vote == 1) {
		alert('Еденица!');
	} else {
		alert('Не еденица!');
	}
	
});
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

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