Динамическое создание обещаний и выполнение последовательно - PullRequest
0 голосов
/ 09 декабря 2018

Я сталкиваюсь со следующей проблемой.

У меня есть следующее обещание (упрощенно):

module.exports.checkVotes = (groupId) =>{
    return new Promise((resolve, reject)=>{
     // some db stuff onoing
     ...
     .then((votes)=>{return resolve(votes}})
     .catch((err)=>{return reject(err}})
    })
}

В какой-то момент я зацикливаюсь на объекте.Для каждой записи я должен назвать обещание выше.Но до начала 2. Обещания, первое должно быть закончено ... и так далее.Я попробовал это, но как только я вызову обещание, оно выполняется.

 .then(()=>{
      for (let i=0;i<groups.length;i++){
           // for each group I want to call the promise later
           //but it executes as soon as I push it.
           tasklist.push(this.checkVotes(groups[i])) 
       }

       return tasklist.reduce((promiseChain, currentTask) => {
           return promiseChain.then(chainResults =>
               currentTask.then(currentResult =>
                    [ ...chainResults, currentResult ]
                )
           );
        }, Promise.resolve([])).then(arrayOfResults => {
                console.log(arrayOfResults)
            }).catch((err) =>{console.log(err)});
         })
  })

Я не могу запустить это с Promise.all (), потому что для некоторых вещей в базе данных мне нужно, чтобы это выполнялось последовательно.Более того, я не могу жестко закодировать это, потому что количество групп является переменным.

Как я могу решить это?

Спасибо за помощь

Ответы [ 2 ]

0 голосов
/ 09 декабря 2018

, кажется, работает так:

groupIds = [12, 45, 34];
return groupIds .reduce((promise, groupId) => {
                return promise.then(() => {
                    return this.checkVotes(groupId)
                        .then((votes)=>{
                            votesList[groupId] = votes
                        })
                        .catch((err)=>{
                            throw err
                        })
                })
            }, Promise.resolve())
0 голосов
/ 09 декабря 2018

Ваша проблема заключалась в размещении обещаний в taskList, а не задач (функций, которые возвращают обещания).Идея заставить их запускаться последовательно - это вызвать их в then обратном вызове в reduce:

return groups.reduce((promiseChain, currentGroup) => {
    return promiseChain.then(chainResults =>
        this.checkVotes(currentGroup).then(currentResult => [...chainResults, currentResult])
//      ^^^^^^^^^^^^^^^
    );
}, Promise.resolve([]))

Но если вы можете использовать async / await синтаксис, вам все равно не нужно делать все это, и вы можете написать гораздо более простой и эффективный

const results = [];
for (const group of groups)
    results.push(await this.checkVotes(group));
...