JavaScript для ... of, for ... in или другие итерационные методы не работают для нескольких вызовов API - PullRequest
0 голосов
/ 17 сентября 2018

Моя цель - получить метаданные о видео из Brightcove CMS API путем передачи идентификаторов видео.

Метаданные нашего видео хранятся в четырех разных бизнес-единицах (или профилях), поэтому я должен запрашивать конечную точку каждого бизнес-подразделения отдельно. Я не знаю, какой идентификатор видео будет найден в каком подразделении. Я могу отправить максимум 10 видео идентификаторов за звонок. Ниже приведены шаги, необходимые для получения метаданных видео по идентификатору видео.

1) Получить доступ token (этот шаг использует учетные данные клиента, которые я предоставляю).

2) Передать доступ token для запроса объекта (sendRequest) через options param.

3) Разобрать ответ и поместить его в глобальный videosArray.

4) Повторите шаги с 1 по 3 для каждого набора из 10 уникальных идентификаторов видео или менее (представленных многомерным массивом).

5) Повторите шаги с 1 по 4 для каждой учетной записи видео (бизнес-единицы).

FYI: шаблонный код от Brightcove использует обратные вызовы. Я преобразовал этот код в async / await. Возможно, кто-то может также предложить улучшения для моего асинхронного / ожидающего кода, если он неверен.

Я использую Узел 8.10 , ES6 + и request-обещание-native (среди прочих). Любые переменные, которые кажутся неявно объявленными, объявляются в глобальной области видимости. Я просто не вставил их сюда.

bizUnit - это массив объектов как таковых (у меня есть четыре различных бизнес-единицы для итерации):

businessUnits = [
     bizUnitOne: {
          account_id: 'uhdafoia98243r2',
          client_id: 'oidahf982y229hr',
          client_secret: 'iuahf9o4398oyg',
          player_url: 'afdhy984wyyfsg',
     },
     bizUnitTwo: {
          account_id: 'uhdafoia98243r2',
          client_id: 'oidahf982y229hr',
          client_secret: 'iuahf9o4398oyg',
          player_url: 'afdhy984wyyfsg',
     }
]

Объявление функции токена доступа:

async function getAccessToken(bizUnit) {
// base64 encode the client_id:client_secret string for basic auth
let bodyObj,
    token;
authString = new Buffer(bizUnit.client_id + ':' + bizUnit.client_secret).toString('base64');
let payLoad = {
    method: 'POST',
    url: 'https://oauth.brightcove.com/v3/access_token?grant_type=client_credentials',
    headers: {
        'Authorization': 'Basic ' + authString,
        'Content-Type': 'application/json'
    },
    json: true
};
try {
    let result = await request(payLoad);
    bodyObj = await JSON.parse(result);
    token = bodyObj.access_token;
    return token;
}
catch (error) {
    console.log(oauthError, error);
}

}

Отправить запрос декларации:

async function sendRequest(options) {
let requestOptions = {
    method: 'GET',
    url: options.url,
    headers: {
        'Authorization': 'Bearer ' + options.token,
        'Content-Type': 'application/json'
    },
    json: true
};
let makeRequest = async (reqOptions) => {
    try {
        let body = await request(reqOptions);
        return JSON.parse(body);
    } catch (error) {
        console.log(apiError, error);
    }
};
// make the request
await makeRequest(requestOptions);

}

Пример массива идентификаторов видео (теоретически в этом массиве могут быть сотни или тысячи идентификаторов видео по 10 и менее блоков):

videoIdsGroup = [ [53245,2352,243252,2352352,234234,234324,2342342,24242,23542,234324], [43534, 34543, 3453, 3453345] ];

Собираем все вместе и делаем запрос:

function setUpVideoRequest(bizUnit) {
(async (bu) => {
    // note that access tokens live for 5 minutes
    // but you can always request one for each call to be safe

    for (let videoIdsArr of videoIdsGroup) {
        let endPoint,
        videoIdsString = videoIdsArr.join();
        endPoint = '/accounts/' + bu.account_id + '/videos/' + videoIdsString + '&sort=' + sort;
        options.url = baseURL + endPoint;
        options.token = await getAccessToken(bizUnit);
        const videos = await sendRequest(options);
        videosArray = videosArray.concat(videos);
    }
})(bizUnit);

}

Инициирование исполнения:

   for (let bu of businessUnits) {

        /*the counter below is to reveal how many times and in what sequence this for...of loop is executing. my console.log indicates that this loop iterates through all businessUnits immediately, but then it runs again and eventually succeeds in some of the calls and repeats those calls even though it already got data.*/ 
        let parentCounter = 0;
        console.log("BizUnit COUNTER", parentCounter++);

        try {
    promises.push(setUpVideoRequest(bu));
} catch (error) {
    throw error;
}

}

Я получаю сообщение об ошибке (это повторяется, а затем я время от времени получаю некоторые данные, а затем ошибка повторяется):

    statusCode: 400,
  message: '400 - {"error":"invalid_client","error_description":"The "client_id" parameter is missing, does not name a client registration that is applicable for the requested call, or is not properly authenticated."}',

Я знаю, что циклы for ... не работают правильно, но я пробовал обычный цикл for с итератором [i], я также пробовал цикл for ... in, и я попробовал для каждого. Ни один из них не работает правильно.

Я просто хочу иметь возможность сделать запрос для идентификатора учетной записи (подразделения) и для массива видео, получить все метаданные видео и поместить их в глобальный videosArray примерно так:

Promise.all(promises).then((results) => {
    promiseVidArray.push(results);
});

Заранее спасибо за вашу помощь и понимание.

Ответы [ 2 ]

0 голосов
/ 21 сентября 2018

После внесения некоторых исправлений в мой синтаксис async / await (спасибо @Bergi) я обнаружил корень проблемы: я отправлял неверные учетные данные клиента для 3 из 4 запросов.Причина довольно интересная.Я подробно изложил это ниже.

Когда вы создаете ключ аутентификации API в Brightcove Video Cloud, вы указываете имя ключа, выбираете бизнес-сегменты для авторизации под этим ключом и выбираете конечные точки, которые вы хотите предоставить в этих бизнес-единицах.

Я создал один ключ для каждой бизнес-единицы, и Brightcove предоставил мне уникальный «account_id», «client_id», «client_secret» для каждого ключа.Я немедленно скопировал / вставил их в файл блокнота, потому что «client_secret» исчезает через 5 минут и не может быть восстановлен (вам придется удалить ключ и создать новый).

Сегодня я снова вошел в панель управления Brightcove, чтобы подтвердить правильность моих ключей.К моему удивлению, все четыре «client_ids» были точно такими же (идентификаторы клиента, которые я скопировал / вставил, были уникальными).В своем запросе API я отправлял уникальный «client_id» для каждой бизнес-единицы, потому что именно это предоставил мне Brightcove при создании ключа аутентификации API.Каким-то образом все они изменились и стали одним и тем же ключом для всех четырех бизнес-единиц.Я до сих пор не понимаю, почему или как это произошло.

Таким образом, мои запросы не выполнялись для 3 из 4 учетных записей.

0 голосов
/ 21 сентября 2018

Вам не хватает закрывающей скобки в объекте businessUnits

businessUnits = [{
     bizUnitOne: {
          account_id: 'uhdafoia98243r2',
          client_id: 'oidahf982y229hr',
          client_secret: 'iuahf9o4398oyg',
          player_url: 'afdhy984wyyfsg',
     },
     bizUnitTwo: {
          account_id: 'uhdafoia98243r2',
          client_id: 'oidahf982y229hr',
          client_secret: 'iuahf9o4398oyg',
          player_url: 'afdhy984wyyfsg',
     }
}]; // <-- Here it is the one you're missing
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...