Вставка в коллекцию после обещаний в метеорном методе
Я использую этот пакет Gumroad-API npm для извлечения данных из внешнего сервиса (Gumroad). К сожалению, кажется, использовать .then()
конструкция, которая может стать немного громоздкой, как вы узнаете ниже:
Это мой метеорный метод:
Meteor.methods({
fetchGumroadData: () => {
const Gumroad = Meteor.npmRequire('gumroad-api');
let gumroad = new Gumroad({ token: Meteor.settings.gumroadAccessKey });
let before = "2099-12-04";
let after = "2014-12-04";
let page = 1;
let sales = [];
// Recursively defined to continue fetching the next page if it exists
let doThisAfterResponse = (response) => {
sales.push(response.sales);
if (response.next_page_url) {
page = page + 1;
gumroad.listSales(after, before, page).then(doThisAfterResponse);
} else {
let finalArray = R.unnest(sales);
console.log('result array length: ' + finalArray.length);
Meteor.call('insertSales', finalArray);
console.log('FINISHED');
}
}
gumroad.listSales(after, before, page).then(doThisAfterResponse); // run
}
});
Поскольку пакет NPM предоставляет API Gumorad, используя что-то вроде этого:
gumroad.listSales(after, before, page).then(callback)
Я решил сделать это рекурсивно, чтобы захватить все страницы данных.
Позвольте мне повторить то, что здесь происходит:
- Путешествие начинается с последней строки кода, показанного выше.
- Начальная страница извлекается, и
doThisAfterResponse()
запускается впервые. - Сначала мы сбрасываем возвращенные данные в наш
sales
массив, а затем мы проверяем, дала ли ответ нам ссылку на следующую страницу (как указание на то, находимся ли мы на последней странице). - Если это так, мы увеличиваем количество страниц и снова вызываем API с той же функцией, чтобы снова обработать ответ.
- Если нет, это означает, что мы на нашей последней странице. Теперь пришло время отформатировать данные, используя
R.unnest
и, наконец, вставитьfinalArray
данных в нашу базу данных.
Но здесь происходит забавная вещь. Все исполнение останавливается на Meteor.call()
и я даже не получаю сообщение об ошибке в журналах сервера.
Я даже пытался отключить Meteor.call()
для простого: Sales.insert({text: 'testing'})
но точно такое же поведение наблюдается.
Что мне действительно нужно сделать, это получить информацию и затем сохранить ее в базе данных на сервере. Как я могу это сделать?
РЕДАКТИРОВАТЬ: Пожалуйста, также посмотрите этот другой (гораздо более упрощенный) ТАК вопрос, который я сделал:
Вызов метеорного метода внутри обратного вызова Promise [Остановка без ошибки]
1 ответ
Я закончил тем, что отказался от пакета NPM и написал свой собственный вызов API. Я никогда не мог понять, как сделать свой звонок внутри .then()
, Вот код:
fetchGumroadData: () => {
let sales = [];
const fetchData = (page = 1) => {
let options = {
data: {
access_token: Meteor.settings.gumroadAccessKey,
before: '2099-12-04',
after: '2014-12-04',
page: page,
}
};
HTTP.call('GET', 'https://api.gumroad.com/v2/sales', options, (err,res) => {
if (err) { // API call failed
console.log(err);
throw err;
} else { // API call successful
sales.push(...res.data.sales);
res.data.next_page_url ? fetchData(page + 1) : Meteor.call('addSalesFromAPI', sales);
}
});
};
fetchData(); // run the function to fetch data recursively
}