JavaScript将Promise推入数组

9

我正在尝试创建一个 Promise 数组,并使用 Promise.all 调用它们。

我在正确将函数推入数组时遇到了问题,它们似乎被立即调用而不是插入并等待 Promise.all()

function findSpecialAbility(players, gameId, message) {
  return new Promise(function(resolve, reject) {
    let playersWithSpecials = _.reject(players, function(p) {
      return p.role === 'alphaWolf' ||
        p.role === 'betaWolf' ||
        p.role === 'villager' ||
        p.role === 'alchemist' ||
        p.targetId === 0 ||
        p.abilityUsed === true;
    });
    if (playersWithSpecials.length === 0) {
      resolve();
    } else {
      let specialsToUse = [];
      for (let i = 0, j = playersWithSpecials.length; i < j; i++) {
        specialsToUse.push(useSpecialAbility(playersWithSpecials[i], gameId, message, players));
      }
      //Promise.all(specialsToUse).then(r = > console.log(r));
    }
  });
}


// Using promise below because some of the role will have database updates.
function useSpecialAbility(playerData, gameId, message, players) {
  return new Promise(function(resolve, reject) {
    if (playerData.role === 'seer') {
      let getTargetData = _.find(players, {
        id: playerData.targetId
      });
      message.guild.members.get(playerData.id).send(`Your target is a ${getTargetData.role}!`);
      resolve('foo');
    }
  });
}

好的.. 当你尝试将函数添加到数组中时,你正在调用该函数。提示:一旦你打开构造函数,它就会运行。 - Adrian
是的,我知道这个问题,只是不知道如何解决它... - Trax
你可以使用对象,在没有构造函数的情况下传递到函数中,并在useSpecialAbility中执行它。 - Adrian
仍然会存在流程控制问题。 - Trax
2个回答

11
似乎它们被调用而不是插入,并等待Promise.all()

// this function returns another function `runnable` and can be called later (synchronously) to get the result
function runLater (index) {
  return function runnable() {
    console.log(`this code is ran later. from ${index}`);
    return `from ${index}`;
  }
}

console.log('this is run now');

const tasks = [];

for (let i = 0; i < 3; i += 1) {
  tasks.push(runLater(i));
}

console.log('this is run');


// use Array.prototype.map to map the array of functions to what they return by invoking each one.
const valuesOfTasks = tasks.map(task => task());
console.log({valuesOfTasks});

console.log('this is run after');
function waitThenSay(milliseconds, message) {
  return new Promise(resolve => {
    console.log(`waiting to say: "${message}"...`)
    setTimeout(() => {
      // log to console for immediate side-effect
      console.log(message.toUpperCase() + '!');
      // also resolve with the message
      resolve(message);
    }, milliseconds);
  });
}

console.log('this is run first');

// tasks is an array of functions that return promises
const tasks = [];
for (let i = 1; i <= 3; i += 1) {
  tasks.push(() => waitThenSay(i * 2000, `hello from task ${i}`));
}

console.log('this is run second');

// execute the tasks by mapping each function to their invocation
const arrayOfPromises = tasks.map(task => task())

// call Promise.all on that array
Promise.all(arrayOfPromises).then(result => {
  console.log({result});
});

希望这能有所帮助!


我需要在继续我的代码之前等待所有的 useSpecialAbility 完成。其中一些将从数据库中读取/写入数据,这就是为什么我使用了 promises。 - Trax

0

我想添加一个相当简单的异步 / await 方法,将 Promise 推入数组,并在以后使用 Promise.all。

async (req, res, next) => {
    try{
        const promises = [];
        
        //Conditionally add promises to the promises array

        if(req.user.hobby === "Hockey")
            promises.push(() => Hobby.find({name: "Hockey"}));

        else
            promises.push(() => Hobby.find({}));

        if(req.user.country === "Canada")
            promises.push(() => User.find({country: "Canada"}));
        
        //Execute the promises in Promise.all()            
                
        const docs = await Promise.all(promises.map(promise => promise()));
    
        if(docs.length === 0){
            var err = new Error('No documents found');
            err.status = 404;
            return next(err);
        }        

        if(docs[1])
            console.log(docs[1]); //array of User docs with country field value set to Canada
    
        console.log(docs[0]); //array of all hobbys or only hobbys with the name field set to Hockey

        res.json(docs);
    }
    catch(err){
        return next(err);
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接