Страницы

Поиск по вопросам

воскресенье, 7 июля 2019 г.

Как сделать синхронным запрос к vk api в цикле через async/await или promise?

Есть следующий код:
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 уже завершается, когда мы получаем ответ в колбеке. Как сделать запрос синхронным?


Ответ

Предполагая, что Ваша проблема в некорректном значении 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();

Комментариев нет:

Отправить комментарий