3

Есть следующий код:

for(let i = 1; i <= length; i++){
    VK.Api.call('groups.getById', {group_id: groups[i].gid, fields: 'description'}, (output) => {
        showVisual(groups[i]);
        console.log(output);
    })
}


Проблема в том, что цикл for уже завершается, когда мы получаем ответ в колбеке.
Как сделать запрос синхронным?

nrjshka
  • 1,256
  • решения также можно глянуть тут https://ru.stackoverflow.com/questions/522468/jquery-ajax-%d0%9e%d0%bf%d1%80%d0%b5%d0%b4%d0%b5%d0%bb%d0%b8%d1%82%d1%8c-%d0%bf%d0%be%d1%81%d0%bb%d0%b5%d0%b4%d0%bd%d0%b8%d0%b9-success – Jean-Claude Nov 06 '17 at 11:27
  • и тут https://ru.stackoverflow.com/questions/554290/%d0%9a%d0%b0%d0%ba-%d0%b2%d0%b5%d1%80%d0%bd%d1%83%d1%82%d1%8c-%d0%b7%d0%bd%d0%b0%d1%87%d0%b5%d0%bd%d0%b8%d0%b5-%d0%b8%d0%b7-%d1%81%d0%be%d0%b1%d1%8b%d1%82%d0%b8%d1%8f-%d0%b8%d0%bb%d0%b8-%d0%b8%d0%b7-%d1%84%d1%83%d0%bd%d0%ba%d1%86%d0%b8%d0%b8-%d0%be%d0%b1%d1%80%d0%b0%d1%82%d0%bd%d0%be%d0%b3%d0%be-%d0%b2%d1%8b%d0%b7%d0%be%d0%b2%d0%b0-%d0%98%d0%bb%d0%b8-%d1%85%d0%be%d1%82%d1%8f-%d0%b1%d1%8b-%d0%b4%d0%be%d0%b6 – Jean-Claude Nov 06 '17 at 11:27
  • Дело в том, что мне нужен именно async/await – nrjshka Nov 06 '17 at 11:33
  • Сделайте promise-обёртку над колбеками, на learn.javascript.ru где-то был такой пример – andreymal Nov 06 '17 at 12:11

1 Answers1

2

Предполагая, что Ваша проблема в некорректном значении i в callback, предлагаю замкнуть значение этой переменной:

for(let i = 1; i <= length; i++){
    VK.Api.call('groups.getById', {group_id: groups[i].gid, fields: 'description'}, ((i) => (output) => {
        showVisual(groups[i]);
        console.log(output);
      })(i)
    );
}

Или, можно добавить в замыкание значение group:

for(let i = 1; i <= length; i++){
  VK.Api.call(
    'groups.getById', 
    {group_id: groups[i].gid, fields: 'description'}, 
    ((group) => 
      (output) => {
        showVisual(group);
        console.log(output);
      }
    )(groups[i])
  );
}

С Promise можно реализовать так:

function getGroupDescription(group) {
  return new Promise(resolve => VK.Api.call(..., resolve));
}

for (let i = 1; i <= length; ++i) {
  getGroupDescription(groups[i]).then(output => console.log(output));
}

Проблема async/await в его каскадном распространении - чтобы его использовать, клиент должен завернуть свой код в async функцию:

function getGroupDescription(group) {
  return new Promise(resolve => VK.Api.call(..., resolve));
}

async function foo () {
 // ...
  for (let i = 1; i <= length; ++i) {
    groups[i].description = await getGroupDescription(groups[i]);
  }
}
foo();

Рабочий пример:

function timedTwice(val, time = 1000) {
  return new Promise(res => setTimeout(() => res(2*val), time));
}

timedTwice(5).then(r => console.log(r));

async function foo() { for (let i = 0; i < 8; ++i) { let result = await timedTwice(i, 100); console.log(i, result); } } foo();

vp_arth
  • 27,179