const runTasks = (tasks, max = 1) =>
new Promise(resolve => {
const results = Array(tasks.length).fill(null);
let started = 0;
let finished = 0;
for (let i = Math.max(1, Math.min(max, tasks.length)); i--; run()) ;
async function run() {
if (finished === tasks.length) {
resolve(results);
} else if (started < tasks.length) {
const index = started++;
try {
results[index] = await tasks[index]();
} catch (e) {
results[index] = e;
}
finished++;
run();
}
}
});
const sendRequests = (urls, ...args) =>
runTasks(urls.map(n => () => fetch(n).then(r => r.json())), ...args);
function parallel(tasks, onAllTasksComplete) {
const results = [];
let numCompleted = 0;
function onTaskComplete(index, result) {
results[index] = result;
if (++numCompleted === tasks.length) {
onAllTasksComplete(results);
}
}
for (let i = 0; i < tasks.length; i++) {
const onComplete = r => onTaskComplete(i, r);
const result = tasks[i](onComplete);
if (result !== undefined) {
onComplete(result);
}
}
}
подскажите, что мне нужно подправить
function makeRequests(urls, max) {
return new Promise(resolve => {
const results = Array(urls.length).fill(null);
const groupedUrls = urls.reduce((acc, n, i) => ((acc[n] ??= []).push(i), acc), {});
const uniqueUrls = Object.keys(groupedUrls);
let countRequests = 0;
let countResponses = 0;
for (let i = 0; i < Math.max(1, Math.min(max, uniqueUrls.length)); i++) {
request();
}
function request() {
if (countResponses === uniqueUrls.length) {
resolve(results);
} else if (countRequests < uniqueUrls.length) {
const url = uniqueUrls[countRequests++];
fetch(url)
.then(result => result.json())
.catch(error => error)
.then(result => {
groupedUrls[url].forEach(n => results[n] = result);
countResponses++;
request();
});
}
}
});
}
const wait = delay => new Promise(r => setTimeout(r, delay));
async function asyncDelayedForEach(data, callback, delay) {
for (let i = 0; i < data.length;) {
await callback.call(data, data[i], i, data);
if (++i < data.length) {
await wait(delay);
}
}
}
const asyncDelayedForEach = (data, callback, delay) =>
Array.prototype.reduce.call(
data,
(promise, n, i, a) => promise
.then(() => callback.call(a, n, i, a))
.then(() => -~i === a.length ? void 0 : wait(delay)),
Promise.resolve()
);
async function chain(arr) {
const result = [];
for (const item of arr) {
result.push(await item(result[result.length - 1]));
}
return result;
}
function chain(arr) {
const result = [];
return arr
.reduce((prev, curr) => prev.then(curr).then(r => (result.push(r), r)), Promise.resolve())
.then(() => result);
}
const last = promises => new Promise((resolve, reject) => {
let pending = promises.length;
if (!pending) {
resolve();
} else {
promises.forEach(n => n
.then(result => --pending || resolve(result))
.catch(error => --pending || reject(error))
);
}
});
async function request(data) {
let result = data;
do {
result = await запрос(result);
} while (result не тот, который нужен);
return result;
}
function requestRecursive(data) {
return запрос(data).then(result => {
return result тот, который нужен
? result
: requestRecursive(result);
});
}
const getNum = () => new Promise(r => setTimeout(r, 1000, Math.random() * 100 | 0));
(async () => {
console.time('xxx');
const [ result1, result2 ] = [ await getNum(), await getNum() ];
console.log(result1, result2);
console.timeEnd('xxx');
})();
(async () => {
console.time('yyy');
const [ result1, result2 ] = await Promise.all([ getNum(), getNum() ]);
console.log(result1, result2);
console.timeEnd('yyy');
})();
выполняются одновременно
new Promise
, чтобы получить желаемую асинхронность. Проведите небольшой эксперимент - откройте консоль, выполнитеconsole.log('щас будем создавать промис');
new Promise(r => {
console.log('создаём промис');
setTimeout(() => {
console.log('так, сейчас дёрнем резолв');
r();
console.log('резолв дёрнули');
});
}).then(() => console.log('зарезолвились, наконец-то'));
console.log('промис создан');
результат времени как при параллельном выполнении
Получается что new Promise( уже запускает на выполнение код? Его можно как то отложить?
const getA = () => new Promise((resolve, reject) => {
console.time('getA');
setTimeout(() => {
console.timeEnd('getA');
resolve(4)
}, 6000)
});
const getB = () => new Promise((resolve, reject) => {
console.time('getB');
setTimeout(() => {
console.timeEnd('getB');
resolve(2)
}, 2000)
});
console.time('get sum');
getA().then(a => {
getB().then(b => {
console.log(`result: ${a + b}`);
console.timeEnd('get sum');
})
});
Среда исполнения JS уже умеет параллельно?