我已经阅读了async/await,在阅读了几篇文章之后,我决定自己测试一下。然而,我似乎不明白为什么这行不通:

async function main() {  
    var value = await Promise.resolve('Hey there');
    console.log('inside: ' + value);
    return value;
}

var text = main();  
console.log('outside: ' + text);

控制台输出以下内容(节点v8.6.0):

> outside: [object Promise] > inside:嘿,大家好

为什么函数内部的日志消息之后执行?我认为创建async/await的原因是为了使用异步任务执行同步执行。

是否有一种方法可以使用函数内部返回的值,而不使用main()后的.then() ?


当前回答

在NodeJS 14.8+中,你可以使用顶级的await模块(#3解决方案)。你也可以将.js重命名为.mjs (ES模块)而不是.js(。cj CommonJS)。

其他回答

我喜欢这种聪明的语法来从入口点执行异步工作

void async function main() {
  await doSomeWork()
  await doMoreWork()
}()

2021年的答案:你现在可以在当前稳定版本的节点中使用顶级等待

上面的大多数答案都有点过时或非常冗长,所以这里有一个关于节点14的快速示例。

创建一个名为runme.mjs的文件:

import * as util from "util";
import { exec as lameExec } from "child_process";
const exec = util.promisify(lameExec);
const log = console.log.bind(console);

// Top level await works now
const { stdout, stderr } = await exec("ls -la");
log("Output:\n", stdout);
log("\n\nErrors:\n", stderr);

运行node runme.mjs

Output:
 total 20
drwxr-xr-x  2 mike mike 4096 Aug 12 12:05 .
drwxr-xr-x 30 mike mike 4096 Aug 12 11:05 ..
-rw-r--r--  1 mike mike  130 Aug 12 12:01 file.json
-rw-r--r--  1 mike mike  770 Aug 12 12:12 runme.mjs



Errors:

这个问题的实际解决方案是采用不同的方法。

可能您的目标是某种初始化,这通常发生在应用程序的顶层。

解决方案是确保在应用程序的顶层只有一个JavaScript语句。如果你在应用程序的顶部只有一条语句,那么你可以在任何地方的其他任何地方自由地使用async/await(当然要遵守正常的语法规则)。

换句话说,把你的整个顶层包装在一个函数中,这样它就不再是顶层了,这就解决了如何在应用程序的顶层运行async/await的问题——你不需要。

这是你的应用程序的顶层应该是这样的:

import {application} from './server'

application();

对于浏览器,你需要添加type="module"

没有类型=“模块”

< >脚本 Const response = await fetch('https://jsonplaceholder.typicode.com/users'); Const users = await sp.json(); console.log(用户) > < /脚本

类型=“模块”

<!——script type="module" src=" wait.js"——> .js . <脚本类型=“模块”> Const response = await fetch('https://jsonplaceholder.typicode.com/users'); Const users = await sp.json(); console.log(用户) > < /脚本

其他解决方案缺乏POSIX兼容性的一些重要细节:

你需要…

成功时报告0退出状态,失败时报告非0退出状态。 向标准输出流发出错误。

#!/usr/bin/env node

async function main() {
 // ... await stuff ... 
}

// POSIX compliant apps should report an exit status
main()
    .then(() => {
        process.exit(0);
    })
    .catch(err => {
        console.error(err); // Writes to stderr
        process.exit(1);
    });

如果使用command等命令行解析器,则可能不需要main()。

例子:

#!/usr/bin/env node

import commander from 'commander'

const program = new commander.Command();

program
  .version("0.0.1")
  .command("some-cmd")
  .arguments("<my-arg1>")
  .action(async (arg1: string) => {
    // run some async action
  });

program.parseAsync(process.argv)
  .then(() => {
    process.exit(0)
  })
  .catch(err => {
    console.error(err.message || err);
    if (err.stack) console.error(err.stack);
    process.exit(1);
  });