Задержка запросов на обещание при запросе информации в Node.js - PullRequest
0 голосов
/ 15 января 2020

Я использую библиотеку gpapi , чтобы найти Play Store и сохранить информацию о приложениях, найденных в Play Store. Я начинаю с поиска соответствующих приложений приложения (около 20 приложений), после чего запрашиваю подробную информацию о каждом из них. Это делается библиотекой как запросы обещаний. Я попытался добавить задержку между запросами, так как в текущем состоянии все запросы выполняются одновременно, поэтому я получаю ошибку 429 (слишком много запросов), и через некоторое время я временно полностью забанен на серверах Google.

function getRelatedApps(pkg) {
    api.login()
        .then(function () {
            api.related(pkg).then(function (res) {
                for (let key in res['0'].child) {
                    let appId = res['0'].child[key].docid;
                    if (!storedApps.has(appId)) {
                        relatedArray.add(appId);
                    }
                }

                Promise.map(relatedArray, function (appId) {
                    getInfo(appId);
                }, {concurrency: 1});
            });
        });
}

Я попытался добавить Promise.delay между каждым запросом и использовать функцию setTimeout без какого-либо эффекта, поскольку запросы все еще выполнялись одновременно.

При использовании while l oop с setTimeout внутри, вообще не было выполнено ни одного запроса.

Как можно сделать паузы между каждым вызовом функции getInfo?

1 Ответ

1 голос
/ 16 января 2020

Если вы используете Bluebird, то вам доступны Promise.map() и Promise.delay(), и вы можете сделать следующее:

function getRelatedApps(pkg) {
    return api.login()
    .then(() => api.related(pkg))
    .then(res => {
        let relatedArray = Object.values(res['0'].child)
            .map(value => value.docid)
            .filter(appId => !storedApps.has(appId));
        return Promise.map(relatedArray, appId => Promise.delay(1000, getInfo(appId)), {concurrency: 1});
    });
}

В противном случае, вы можете добиться того же эффекта с домашним функция delay() * и шаблон Array.prototype.reduce () :

function delay(ms, val) {
    return new Promise(resolve => {
        setTimeout(() => { resolve(val); }, ms);
    });
}
function getRelatedApps(pkg) {
    return api.login()
    .then(() => api.related(pkg))
    .then(res => {
        return Object.values(res['0'].child)
        .map(val => val.docid)
        .filter(appId => !storedApps.has(appId));
        .reduce((p, appId) => p.then(() => delay(1000, appId)).then(getInfo), Promise.resolve());
    });
}

Примечания:

  1. Объект. значения () доступны из Node.js 7.0.0. Для более ранних версий Node вернитесь к построению relatedArray, как в вопросе.
  2. Предполагается, что вопрос relatedArray изначально пуст.
  3. Отрегулируйте задержку 1000 мс по мере необходимости.
...