无法理解async / await nodejs

时间:2018-05-02 19:32:36

标签: javascript node.js asynchronous mongoose promise

好的,所以我很难理解nodejs中async / await,Promises等是如何工作的,这是我第一次用异步语言编程。

我在这里尝试做的基本上是从猫鼬模型“SecSolution”中选择一个随机条目。目前,当返回arr时它是空的,并且在打印顶部的调试之前打印底部的调试消息。 我只是希望函数在获得其值后返回“arr”。

async function getRandomCardIds(deckIdentifier, cardCount) {
    let arr;
    switch (deckIdentifier) {
        case 102:
            await SecSolution.count().exec(async function (err, count) {
                let promises = [];
                var random = Math.floor(Math.random() * count);
                for (let i = 0; i < 2; i++) {
                    promises.push((await SecSolution.findOne().skip(random).lean())._id);
                }
                arr = await Promise.all(promises);
                debug("This gets printed second" + arr);
            });
            break;
    }
    debug("this gets printed first");
    return arr;
}

提前致谢!

2 个答案:

答案 0 :(得分:1)

使用async / await时请勿使用回调。 (使用简单承诺时,只使用 then回调)。此外,您不应将await用于您仍需要作为承诺对象的承诺,以将其传递给Promise.all。你的代码应该是

async function getRandomCardIds(deckIdentifier, cardCount) {
    switch (deckIdentifier) {
        case 102:
            const count = await SecSolution.count(); // a promise(like object)
            let promises = [];
            var random = Math.floor(Math.random() * count);
            for (let i = 0; i < 2; i++) {
                promises.push(SecSolution.findOne().skip(random).lean());
            }
            let arr = await Promise.all(promises);
            debug("This gets printed second" + arr);
            return [arr[0]._id, arr[1]._id];
            break;
    }
    debug("this gets printed first");
    return undefined;
}

您可以直接转换promises(类似于您使用_id尝试的内容),而不是访问结果数组中对象的await

promises.push(SecSolution.findOne().skip(random).lean().then(card => card._id));

答案 1 :(得分:0)

基本上你必须认为它会尝试运行所有东西,所有需要等待解决的代码都不会停止运行所有代码的过程。

因此,查看您的代码,我们可以看到以下内容:

1)将arr定义为undefined然后进入开关。

2)在switch语句中我们有一个await所以它会等待(但是它不会停止运行其他代码,因为它不在同一个语句中),它会稍后解决。

3)打印debug消息

4)返回undefined因为切换内部的等待未解决。

5)有一天声明得到了解决,但你无能为力。

可以是以下示例。

&#13;
&#13;
function resolveAfter2Seconds() {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve('resolved');
    }, 2000);
  });
}

async function asyncCall() {
  console.log('calling');
  var result = await resolveAfter2Seconds();
  console.log(result);
  // expected output: "resolved"
}

asyncCall();
&#13;
&#13;
&#13;

所以你可以做的就是以下内容:

&#13;
&#13;
function resolveInnerFunct() {
  return new Promise(resolve => {
    let promises = [];
    var random = Math.floor(Math.random() * count);
    for (let i = 0; i < 2; i++) {
      promises.push(SecSolution.findOne().skip(random).lean())._id));
    }
    Promise.all(promises).then(values=> {return resolve(values)};
  });
}

async function asyncCall() {
  console.log('calling');
  let arr;
  switch (deckIdentifier) {
    case 102:
      // this will wait until the resolveInnerFunct resolves.
      arr = await resolveInnerFunct();
      debug("this wont get printed before the other message")
      break;
  }
  debug("this gets printed first");
  return arr;
}

asyncCall();
&#13;
&#13;
&#13;