0

Здравствуйте. Не могу понять в чем загвоздка. Пишу простую функцию, как на примере ниже:

function setCookie(val)
{
    var arr = new Object();

    $.ajax({
        type: 'post',
        dataType: 'json',
        url: 'index.php',
        data:
        {
            val: val,

            query: 'set-cookie'
        },
        success: function(data)
        {
            // тут возвращается, как и должно, число и без массивов: 100
            console.log(data);
            // заношу в объект число, которое пришло с запроса
            arr = { 'data': data };
        }
    });

    // в итоге мне возвращается: Object {} undefined
    console.log(arr, arr['data']);
    return arr;
}

Значение теряются при занесении в объект. Как занести в объект то, что пришло с запроса? Вроде в верху создал нужную глобальную переменную, а результат никакой.

J. Doe
  • 157

2 Answers2

3

Так ничего не выйдет.
Код асинхронный, т. е. выполняется не сразу, а... когда-то в будущем.
Для этого можно использовать Promise:

function setCookie(val)
{
  return new Promise((resolve, reject) => { // Оборачиваем код в обещание
    $.ajax({
        type: 'post',
        dataType: 'json',
        url: 'index.php',
        data:
        {
            val: val,
            query: 'set-cookie'
        },
        success: function(data)
        {
            // тут возвращается, как и должно, число и без массивов: 100
            console.log(data);
        resolve({ 'data': data });
    }
});

}); }

setCookie(value).then(res => { console.info(res); // { 'data': 100 } });

Но это больше на костыль (работающий, но костыль) похоже, в ES2017 обещают Async/Await - это уже лучше.

  • Спасибо, я завтра гляну, что получится. – J. Doe Aug 06 '16 at 20:21
  • Вот только для полноценного использования Promise и функций-стрелок автору вопроса придется подключать полифилл и транслировать код с помощью babel. Хотя для решения проблемы достаточно вернуть из функции setCookie результат выполнения команды $.ajax(...), к которому во внешней среде так же можно приписать обработчик с помощью .then http://api.jquery.com/deferred.then/ – qodunpob Aug 07 '16 at 02:56
  • @КонстантинБашаркевич, jQuery имеет свою реализацию promise, поэтому никакие полифиллы в данном случае не нужны, как впрочем и явное использование нативных промисов – Grundy Aug 07 '16 at 09:25
  • @Grundy ну так я о ней и говорю =) – qodunpob Aug 07 '16 at 09:39
  • Подскажите как её вызывать со своими значениями, что-то у меня не получается. Вариант, setCookie.then('...'); не работает. – J. Doe Aug 07 '16 at 09:47
  • @J.Doe setCookie.then('...'); не работает потому что должно быть setCookie(val).then('...');, а вообще рекомендую обратить внимание на мой комментарий выше. – qodunpob Aug 07 '16 at 09:58
  • @КонстантинБашаркевич теперь понял, спасибо – J. Doe Aug 07 '16 at 10:04
0

Похоже дело в том что код является асинхронным и в переменную ещё и в правду нечего не записано, но можно сделать синхронный запрос добавив

async: false,

после

url: 'index.php',

но тогда вкладка на момент запроса будет "заблокирована" и не будет выполнятся какой либо код до завершения запроса, лучше писать асинхронный код но его писать тяжелее.