2

Привет. Допустим, что я хочу вывести какой-то блок на странице:

$('.some-element').append(`
Привет, ${data.user_name}. Вы успешно зарегистрировались в системе. Ваш город определён, как ${getCityByCode(data.code)}`
);

Но дело в том, что в функции getTimeByCode() используется асинхронный ajax-запрос, например:

function getCityByCode(param) {
    $.getJSON('/json/cities.json', function(json){
        for(let i = 0; i < json.length; i++)
            if(json[i].code == param)
                return json[i].cityname;
    })
}

А следственно, функция append() не будет ждать, пока выполнится функция getCityByCode(). Для этого нежно использовать Promise. Но как это правильно сделать? Как заставить append() дожидаться выполнения функции?

  • а почему аппенд не всунуть вместо ретурна скажем ? – Rostyslav Kuzmovych Jun 27 '17 at 19:14
  • @RostyslavKuzmovych а если у меня 5-6 таких асинхронных функций будет? – JamesJGoodwin Jun 27 '17 at 19:41
  • ну 5-6 раз вызвать ajax запрос, каждый раз передавая ему колбэк функцию на саксес, а с промисами будет 5-6 промисов, в которые будут передаваться колбэк функции, я это все вижу именно так – Rostyslav Kuzmovych Jun 27 '17 at 19:48
  • @RostyslavKuzmovych не 5-6 одинаковых вызовов, а 5-6 вызовов разных функций, в которых должны быть промисы. – JamesJGoodwin Jun 27 '17 at 19:51
  • никто и не говорил об одинаковых, 5-6 аяксов или 5-6 промисов, особой разницы не вижу – Rostyslav Kuzmovych Jun 27 '17 at 19:53
  • Тогда у меня будет 5-6 вложенных циклов в теле 5-6 асинхронных вызовов? не ужас ли? – JamesJGoodwin Jun 27 '17 at 19:59
  • если функция с циклом одна и та же, то можно ее вынести в отдельную – Rostyslav Kuzmovych Jun 27 '17 at 20:02

1 Answers1

1

Все верно, append не будет ждать запроса, более того в вашей конструкции не получится вернуть cityname напрямую, как результат работы функции getCityByCode.

В данном случае можно использовать Promise, необходимо, чтобы функция getCityByCode возвращала объект Promise, в который нужно передавать асинхронную функцию, которая по завершении действия должна вызвать один из аргументов resolve или reject.

Должно получиться как-то так:

function getCityByCode(param) {
    return new Promise(function(resolve, reject) {
        $.getJSON('/json/cities.json', function(json) {
            for (let city of json) {
                if (city.code == param) {
                    resolve(city.cityname);
                }
            }
        })
    });
}

getCityByCode(data.code)
    .then(function(cityName) {
        $('.some-element').append(cityName);
    });