Я добавлю еще один ответ, потому что принятый ответ не предусматривает следующее:
- уведомления, когда все запросы выполняются
- Представление результатов в порядке
- Обработка ошибок
- Любой контроль параллелизма, чтобы решить, сколько запросов выполняется одновременно (может быть важно для ограничения скорости твиттера)
Это первое решение использует библиотеку обещаний Bluebird, потому что это значительно упрощает ситуацию. в частности, для управления параллелизмом:
const Promise = require('bluebird');
const fs = Promise.promsifyAll(require('fs'));
const fetch = require('node-fetch);
function getSingleCreationDate(item) {
return fetch('http://mytwitterbirthday.com/api/?screen_name=' + item).then(function(response) {
return response.json();
});
}
function getAllCreationDates(file) {
return fs.readFileAsync(file).then(function(data) {
let array = data.toString().split("\n");
// put whatever concurrency value here works best, higher is more parallelism
// lower is more protection from being rate limited by the host
return Promise.map(array, getSingleCreationDate, {concurrency: 4});
});
}
getAllCreationDates('file.txt').then(function(results) {
// process array of results here (in order)
}).catch(function(err) {
// handle error here
});
Это второе решение использует стандартные ES6 обещания и упорядочивает запросы как исходный код в OP в:
const fs = require('fs');
const fetch = require('node-fetch);
// promisify readFile
fs.readFileAsync = function(file, options) {
return new Promise(function(resolve, reject) {
fs.readFile(file, options, function(err, data) {
if (err) return reject(err);
resolve(data);
});
});
}
function getSingleCreationDate(item) {
return fetch('http://mytwitterbirthday.com/api/?screen_name=' + item).then(function(response) {
return response.json();
});
}
function getAllCreationDates(file) {
return fs.readFileAsync(file).then(function(data) {
let array = data.toString().split("\n");
let results = [];
return array.reduce(function(p, item) {
return p.then(function() {
return getSingleCreationDate(item).then(function(twitterData) {
results.push(twitterData);
});
})
}, Promise.resolve()).then(function() {
// make array of results be the resolved value
return results;
});
});
}
getAllCreationDates('file.txt').then(function(results) {
// process array of results here (in order)
}).catch(function(err) {
// handle error here
});
Или, если твиттер прекрасно с вами посылая все запросы сразу , вы можете сделать это:
const fs = require('fs');
const fetch = require('node-fetch);
// promisify readFile
fs.readFileAsync = function(file, options) {
return new Promise(function(resolve, reject) {
fs.readFile(file, options, function(err, data) {
if (err) return reject(err);
resolve(data);
});
});
}
function getSingleCreationDate(item) {
return fetch('http://mytwitterbirthday.com/api/?screen_name=' + item).then(function(response) {
return response.json();
});
}
function getAllCreationDates(file) {
return fs.readFileAsync(file).then(function(data) {
let array = data.toString().split("\n");
return Promise.all(array.map(function(item) {
return getSingleCreationDate(item);
}));
});
}
getAllCreationDates('file.txt').then(function(results) {
// process array of results here (in order)
}).catch(function(err) {
// handle error here
});
Примечание: Это запустит все запросы сразу (параллельно - тогда как исходный код делал их серийно, если это имеет значение для ограничения скорости), и c ode необходимо добавить либо для получения результата по порядку, либо для того, чтобы узнать, когда все результаты будут выполнены. Это само по себе не очень полезно - только часть решения. – jfriend00
Это не «пользователь очереди», он запускает каждый запрос сразу. – Hitmands
@Hitmands: Да, я упомянул в ответе, что: «Я полагаю, вам не нужно печатать выходы в том же порядке, что и в массиве». – thameera