@lacront

Можно ли упросить решение задачи с Promise?

Есть задачка. Необходимо реализовать последовательное и параллельное выполнение цепочки промисов. (при параллельном не использовать Promise.all, также не использовать async/await). Результат - массив, как при Promise.all, порядок такой же как и у переданных аргументов. Я это вроде выполнил, но хотелось бы узнать нет ли способа оптимальнее? Заранее спасибо за ваши ответы.
function parallel(funcArray, doneAll) {
   const newArray = [];
   const result = funcArray.map(item => new Promise(resolve => item(resolve)));
   const array = result.reduce((a, curr, i, array) => {
     return a.then((res) => {
       curr.then(res => {
         newArray.push(res);
         if (array.length === i+1) {
           doneAll(newArray);
         }
       })
       return curr
     });
   }, Promise.resolve());
}

function inSeries(funcArray, doneAll) {
   const newArray = [];
   const array = funcArray.reduce((a, curr, i, array) =>
     a.then(
       () => new Promise(
         resolve => {
           curr(resolve)
         }).then(res => {
           newArray.push(res);
           if (array.length === i+1) {
             doneAll(newArray);
           }
         })
       ),
     Promise.resolve())
}

var a = function(done) {
  setTimeout(function() {
    done('result a');
  }, 600);
};

var b = function(done) {
  setTimeout(function() {
    done('result b');
  }, 200);
};

parallel([a,b], function(results) {
  console.log(results); // ['result a', 'result b']
});
inSeries([a,b], function(results) {
  console.log(results); // ['result a', 'result b']
});
  • Вопрос задан
  • 220 просмотров
Решения вопроса 1
rockon404
@rockon404
Frontend Developer
1. Ваши реализации выполняют не массив Promise, а массив вызовов:
function(done) {
  setTimeout(function() {
    done('result');
  }, duration);
};


Скорей всего, вам надо было выполнять таски вида:
new Promise(resolve => { 
  setTimeout(resolve, duration, 'result'); 
});


2. Называйте функции и аргументы по-человечески, а не array, newArray, funcArray.

3. Для параллельного выполнения с вызовом колбека done, достаточно:
function all(promises, done) {
  const results = [];
  let count = promises.length;
  const checkDone = () => {
    if (--count === 0) done(results);
  };
  
  promises.forEach((p, i) => {
    p.then(x => results[i] = x).then(checkDone);
  });
}

Для имитации Promise.all:
function promiseAll(promises) {
  return new Promise(resolve => {
    const results = [];
    let count = promises.length;
    const checkDone = () => {
      if (--count === 0) resolve(results);
    };
  
    promises.forEach((p, i) => {
      p.then(x => results[i] = x).then(checkDone);
    });
  });
}


Реализацию последовательного выполнения прикладывать не буду, так как ее ну слишком просто найти в поисковике.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы