【问题标题】:Promise.all() and .then issuePromise.all() 和 .then 问题
【发布时间】:2017-11-23 03:41:07
【问题描述】:

我正在尝试在 node.js 中进行一些堆栈操作 基本上我试图让下面的代码工作。问题是弹出发生在推送之前,我得到“空堆栈”错误。

const stack = new stack;

findAllOfA()
.then(allA => {                         //first then
  return Promise.all(allA.map(A => {
  stack.push(a);
  });
})
.then(() => {                           //second then
  var topA = stack.pop();
  //Do some things with topA
}

我想我应该从 map 的函数中返回一些东西,但我不知道要返回什么来确保第一个 then 在调用第二个 then 之前被填充。

这是伪代码(真实代码相当混乱) 真正的代码来了(小心)

const catStack = new dataStructures.Stack();
  let layer = 0;

  //Generic while promise function
  function promiseWhile(predicate, action) {
    console.log('in while');
    function loop() {
      if (!predicate) return;
      return Promise.resolve(action()).then(loop);
    }
    return Promise.resolve().then(loop);
  }

  categoryFacade.findAllMainCategories()
    .then((mainCategories) => {
      return Promise.all(mainCategories.map((mainCategory) => {
        console.log(JSON.stringify(mainCategory.name, null, 0));
        catStack.push(mainCategory);
        return mainCategory;
      }));
    })
  .then(promiseWhile(!catStack.empty(), function() {
    console.log('in action');
    let nextToProcess = catStack.pop();
    layer += 2;
    console.log(JSON.stringify(nextToProcess.name, null, layer));
    return categoryFacade.findAllChildrenOf(nextToProcess.name)
    .then(allChildren => Promise.all(allChildren.map((child) => {
      catStack.push(child);
      return child;
    })));
  }))

【问题讨论】:

  • const stack = new stack; 没有意义——它会产生解析错误。还缺少右括号。另外,Aa??但是经过这些更正后,代码可能仍然很奇怪,但它会在弹出之前产生推送。请提供一个能重现您的问题的 sn-p。
  • 语法错误太多

标签: javascript asynchronous promise


【解决方案1】:

Promise.all() 接受价值或承诺。所以你可以直接返回a

您的实际代码是否比您展示的示例更复杂?

我认为没有必要使用Promise.all()

findAllOfA().then(allA => {
  allA.map(stack.push)
}).then(() => {
  const topA = stack.pop()
})

// or
findAllOfA().then(allA => allA.shift()).then(topA => {...})

如果您的第一个 then() 涉及一些异步函数,您将在手边为 allA 中的每个条目提供一个 Promise 对象,您只需返回该 Promise 以供 Promise.all() 等待。

编辑:您的问题是您的 promiseWhile() 在评估时执行,而不是在调用 then() 时执行。

你所需要的.then(() => promiseWhile(...))

【讨论】:

  • return a still make second then go before first then
【解决方案2】:

这段代码真的没有意义。您在一系列承诺上使用Promise.all()。但是,这不是您要传递的内容。

此外,您还缺少一些正确包含 .map() 的括号。您展示的代码甚至无法通过 Javascript 解析器。

正如在别处提到的,const stack = new stack 也是错误的。您需要使用与构造函数名称不同的变量名称。

为了向您展示正确的代码,我们需要了解您的代码中什么是承诺,什么不是承诺。

如果allA 是一组可以解析为您想要的结果的承诺,那么您可以这样做:

Promise.all(allA).then(results => {
   // process resolved results of all the promises in allA array
});

如果allA 是一个数据数组,您希望调用某个函数返回一个promise(这通常是您将Promise.all().map() 结合起来的原因,那么您可以这样做:

Promise.all(allA.map(A => { someFunctionThatReturnsPromise(A) }))
  .then(results => {
      // process results here
  }).catch(err => {
      // process error here
  });

而且,如果这里根本没有异步操作,那么就单独使用.map()

let results = allA.map(A => {
    // process A here
    return some processed version of A
});

// process results here

或者,如果您只想迭代数组,那么只需使用 for/of,您就可以在该循环中做任何您想做的事情。

for (let A of allA) {
   // do whatever you want with A here
}

【讨论】:

  • 我没有函数“someFunctionThatReturnsPromise(A)”,我只想将 A 推入堆栈。返回 A 的 som 处理版本仍然无济于事,因为 second then 仍然在 first then 之前执行。
  • @HenrikStåhlberg - 如果您在这里根本没有异步操作,那么根本没有理由使用Promise.all()。只需单独使用.map().forEach()。在您向我们展示您的承诺在哪里以及您在哪里进行异步操作之前,我们无法通过Promise.all() 为您提供进一步的帮助!根据定义,`p.then() 是异步的,它弄乱了顺序代码。因此,如果您还没有异步代码,请不要使用它。而且,当您将它用于异步代码时,您必须正确使用它。看看我在答案末尾添加了什么。
  • @HenrikStåhlberg - 哦,我看到你刚刚编辑了你的问题而没有告诉任何人。没关系。事实证明,您最初的问题(我花了相当多的时间试图回答)与实际代码中的问题无关。请在下次开始时发布您的 REAL 代码,这样我们就可以减少尝试理解 REAL 问题的时间。
猜你喜欢
  • 1970-01-01
  • 2016-01-09
  • 2018-10-11
  • 1970-01-01
  • 2020-10-14
  • 2017-08-28
  • 2018-07-25
  • 2021-01-19
  • 2021-06-06
相关资源
最近更新 更多