@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']
});
  • Вопрос задан
  • 71 просмотр
Решения вопроса 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);
    });
  });
}


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

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

Войти через TM ID
Похожие вопросы
Digital Sharks Казань
от 60 000 до 65 000 руб.
CS Money Санкт-Петербург
от 120 000 до 150 000 руб.
21 янв. 2019, в 07:08
700 руб./в час
21 янв. 2019, в 01:19
10000 руб./за проект
20 янв. 2019, в 22:33
30000 руб./за проект