const promiseRace = promises => (
new Promise((fulfil, reject) => {
promises.forEach((promise, index) => {
promise.then(data => fulfil({ data, index }), reject);
});
})
);
class Fetcher {
constructor(maxConnections = 20) {
this.maxConnections = maxConnections;
}
async request(urls, options = {}) {
const responsePromises = [];
for (const url of urls) {
if (responsePromises.length >= this.maxConnections) {
const { data: response, index } = await promiseRace(responsePromises);
responsePromises.splice(index, 1);
}
responsePromises.push(fetch(url, options));
}
return Promise.all(responsePromises);
}
}
// test
(async () => {
try {
const fetcher = new Fetcher(2); // лимит 2
const urls = [];
for (let i = 0; i < 200; i++) {
urls.push(`/api/user/${i}`);
}
const responses = await fetcher.request(urls);
console.log('end');
} catch (e) {
console.error(e);
}
})();
// Создаётся объект promise
// не происходит ничего, просто сохраняется объект
let promise = new Promise((resolve, reject) => {
// МЕТКА №1 (см.ниже)
// выполняется setTimeout()
// цифра 1 на картинке, код сейчас здесь
setTimeout(() => {
// цифра 2 на картинке, через секунду (или когда у процессора будет время)
// интерпретатор JS будет разбирать timer queue и выполнит коллбек resolve()
// тем самым "разрешит" промис
resolve("result");
}, 1000);
});
// promise.then навешивает обработчики на успешный результат или ошибку
promise
// GOTO метка №1
.then(
result => {
// первая функция-обработчик - запустится при вызове resolve
// в Timer Queue (возможно) будет ссылка на эту функцию, и она вызовется с аргументом result
alert("Fulfilled: " + result); // result - аргумент resolve
},
error => {
// вторая функция - запустится при вызове reject
// в Timer Queue (возможно) будет ссылка на эту функцию, и она вызовется с аргументом result
alert("Rejected: " + error); // error - аргумент reject
}
);
order: [{
product: ObjectId,
quantity: Number
}]
"scripts": {
"dev": "concurrently \"cd server && npm start\" \"cd client && npm start \"",
"build": "cd client && npm run build",
"install": "(cd server && npm install) && (cd client && npm install)",
"start:prod": "cd server && npm run start:prod",
"heroku-postbuild": "npm run build"
},
"dependencies": {
"concurrently": "^3.5.1"
}
}