无法理解 async/await nodejs
Posted
技术标签:
【中文标题】无法理解 async/await nodejs【英文标题】:Trouble understanding async/await nodejs 【发布时间】:2018-10-13 00:14:59 【问题描述】:好吧,我在理解 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;
提前致谢!
【问题讨论】:
你确定random
不应该在循环内吗?
是的,你是对的,还没有注意到,因为它没有返回任何东西:)
【参考方案1】:
在使用 async
/await
时不要使用回调。 (当使用简单的 Promise 时,only then
回调)。此外,您不应在仍需要作为 Promise 对象的 Promise 上使用 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;
除了访问结果数组中对象的_id
s,您还可以直接转换promise(类似于您尝试使用await
):
promises.push(SecSolution.findOne().skip(random).lean().then(card => card._id));
【讨论】:
只是另一个简单的问题,因为我喜欢像你说的那样直接转换承诺的巧妙技巧:promises.push(SecSolution.findOne().skip(random).lean().then(card => card._id));
我如何使用 find() 而不是 findOne() 来完成这个?【参考方案2】:
嗯,基本上你必须认为它会尝试运行所有内容,并且所有需要等待解析的代码不会停止运行所有代码的过程。
因此,查看您的代码,我们可以看到以下内容:
1) 将arr
定义为undefined
然后进入开关内部。
2) 在 switch 语句中我们有一个await
,所以它会等待(但它不会停止其他代码的运行,因为它不在同一个语句上),它会在稍后解决。
3) 打印debug
消息
4) 返回undefined
,因为 switch 内部的 await 没有解析。
5) 有一天声明解决了,但你无能为力。
一个例子如下。
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();
所以你可以在你的情况下做如下:
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();
【讨论】:
以上是关于无法理解 async/await nodejs的主要内容,如果未能解决你的问题,请参考以下文章