Promise.all()和.then问题

时间:2017-11-22 19:16:36

标签: javascript asynchronous promise

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

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
}

我想我应该从地图中的函数中返回一些内容,但我不知道返回什么以确保第一个然后在第二个之前被填满然后被调用。

这是psudocode(真正的代码非常杂乱) 这是真正的代码(小心)

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;
    })));
  }))

2 个答案:

答案 0 :(得分:2)

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.all()的承诺等待

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

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

答案 1 :(得分:2)

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

此外,您缺少一些正确包含.map()的parens。您展示的代码甚至无法通过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 /,你就可以在那个循环中做任何你想做的事。

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