Hello. I use VK API in my application to get users of the specified groups. I use, accordingly, the groups.getMembers method.
All is good, but in the answer come less data. For example, the query specifies count = 800, and only 650 users arrive. Only on the first request in the chain comes as much as necessary (because there are a lot of users, I break everything into several requests), and in the others it is less. The result is a noticeable shortage.
Requests are made on timeout, i.e. deferred.
Here is the code:
var DELAY_PER_REQUEST = 600; var COUNT = 800; var OFFSET_STEP = COUNT; var callbackRegistry = {}; var requiredDelay = 0; var membersDataCollection = { count: 0, users: [] }; ... // Выполнить запрос function execRequest(method, params, callback){ var url = VK_URL + method + '?'; for (var param in params){ url += param + '=' + params[param] + '&'; } var callbackName = generateCallbackName(); url += 'callback=RequestManager.callbackRegistry.' + callbackName; callbackRegistry[callbackName] = function(data) { scriptOk = true; delete callbackRegistry[callbackName]; callback(data); deleteRequestScript(callbackName); }; var script = document.createElement('script'); script.onload = script.onerror = function(){ if (scriptOk) return; delete callbackRegistry[callbackName]; }; script.src = url; script.setAttribute('data-callback', callbackName); document.body.appendChild(script); } // Получить часть членов группы function getPartMembers(groupId, params, callback, delay, offset, offsetStep){ params.offset = offset; // Коллбек для сбора всех пользователей var requestCollectCallback = function(data){ if (!data || !data.hasOwnProperty('response')) return; if (offset === 0){ membersDataCollection.count = data.response.count; } console.log('Response users.len = ' + data.response.users.length); membersDataCollection.users = membersDataCollection.users.concat(data.response.users); var message = 'Идет загрузка пользователей сообщества {' + groupId + '}. Загружено ' + membersDataCollection.users.length + '/' + data.response.count + ' пользователей. Подождите пожалуйста.'; $waitingMesage.text(message); if ( (offset + offsetStep) >= data.response.count ) { callback(membersDataCollection); } } if ( !delay ) { execRequest(GROUPS_METHODS.getMembers, params, requestCollectCallback); return; } setTimeout(function(){ execRequest(GROUPS_METHODS.getMembers, params, requestCollectCallback); }, delay); } ... // Получить членов группы getMembers: function(groupId, membersCount, callback, delay, isLastGroup){ var params = { group_id: groupId, count: COUNT, fields: 'domain,photo_50' }; var iterations = Math.ceil( membersCount / COUNT ); console.log( 'Iterations', iterations ); membersDataCollection.count = 0; membersDataCollection.users = []; for (var i = 0; i < iterations; i++){ getPartMembers( groupId, params, callback, ( delay + (DELAY_PER_REQUEST * i) ), (OFFSET_STEP * i), OFFSET_STEP ); } // обнулям счетчик задержки, чтобы на следующих сериях запросах небыло большой задержки requiredDelay += (iterations * DELAY_PER_REQUEST); if (isLastGroup) requiredDelay = 0; } The result is the result in the console:
Iterations 5 bundle.js:96 Response users.len = 800 bundle.js:96 Response users.len = 572 bundle.js:96 Response users.len = 572 bundle.js:96 Response users.len = 572 bundle.js:96 Response users.len = 572 bundle.js:341 Object {count: 3772, users: Array[3088]} Accordingly, there should be 800 people in each request, but starting from the 2nd, for some reason, everything is smaller.
And, interestingly, if you run calls without a timeout, then, as a result, all users come.
Why is this happening and how to solve this problem? (Using deferred calls)