Javascript将Promise放入数组

Tra*_*rax 4 javascript arrays function es6-promise

我正在尝试创建一个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');
    }
  });
}
Run Code Online (Sandbox Code Playgroud)

Ric*_*ler 6

似乎他们被称为而不是插入并等待 Promise.all()

似乎您希望在调用中同时运行promise中的代码Promise.all

如果那是您想要的,那么将代码包装在Promise中可能不是您想要的。


取而代之的是,您需要将要稍后运行的代码包装在一个普通的ole函数中。您可以将这些函数添加到数组中,然后在循环中调用每个函数。从代码的外观来看,您甚至可能甚至不需要承诺。

请参阅以下示例:

// 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');
Run Code Online (Sandbox Code Playgroud)


仅在处理异步控制流时才需要promise。只需将一段代码包装在函数中,即可同步执行延迟执行。当您想执行该代码时,只需调用该函数即可。

编辑:

在继续我的代码之前,我需要等待所有useSpecialAbility完成。其中一些会从数据库写入/读取数据,这就是我使用Promise的原因。

在那种情况下,您将必须使用,Promise.all但是如果希望它们全部同时运行,则仍然需要将这些promise包装在不带参数的函数中。


promise的代码块实际上是同步运行的(与调用.then或时运行该块相对Promise.all),因此,如果您仍然希望以后运行promise,您仍然可以将它们包装在函数中。

请参阅以下示例:

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});
});
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助!