所以我有这段代码,我正在尝试全面深入地理解 async/await 语法。以下是代码的 Promise 版本:
function callToolsPromise(req) {
return new Promise((resolve, reject) => {
let pipshell = 'pipenv';
let args = ['run', 'tools'];
req.forEach(arg => {
args.push(arg)
});
tool = spawn(pipshell, args);
tool.on('exit', (code) => {
if (code !== 0) {
tool.stderr.on('data', (data) => {
reject(data);
});
} else {
tool.stdout.on ('data', (data) => {
resolve(JSON.parse(data)):
});
}
});
})
}
我有一些我想在 tools/__main__.py 中执行的 python 代码,所以这就是我调用“pipenv”的原因。
这是我尝试以 异步/等待 方式编写它(实际上有效):
async function callToolsAsync(req) {
let pipshell = 'pipenv';
let args = ['run', 'tools'];
req.forEach(arg => {
args.push(arg)
});
let tool = spawn(pipshell, args);
for await (const data of tool.stdout) {
return data
}
}
但我所做的只是从某人的示例中复制并粘贴我有 for await...
循环。
因此,我一直在尝试重写相同的代码,以便我能够真正理解它,但我已经失败了好几天了。
有没有其他方法可以在不使用 for await...
循环的情况下使用 异步/等待 方式编写此代码?
我也不知道如何访问数据,除了使用 .then
语法:
callToolsAsync(['GET','mailuser'])
.then(console.log)
我还能如何从 resolve(data)
访问“数据”?
非常感谢。
原文由 tinnick 发布,翻译遵循 CC BY-SA 4.0 许可协议
使用
async/await
编写代码可能没有比在 Node.js 中使用for async (chunk of stream)
语法 更好的 方法了。节点流专门实现了一个异步迭代器来允许这样做。这篇 关于2ality的文章 有更深入的解释和讨论。关于 Symbol.asyncIterator 和 for-await…of 的 MDN 文章更普遍地涵盖了异步迭代。
一旦决定使用异步迭代,就必须在
async
函数中使用它,它将返回一个承诺。虽然在返回的承诺上使用
then
子句是获取数据的完全正常方式,但您也可以await
结果callToolsAsync(req)
4 -a344该调用在async
函数中编码,以便await
处于有效上下文中。以下代码 实验 获取
stdio
和stderr
输出,以及子进程的退出代码。它不使用 Python 或解析数据。main.js (输入
node main.js
运行)孩子.js
这表明
for await (chunk of stream)
循环似乎一直循环到流关闭 - 在这种情况下意味着await
将等待当时没有可用数据的开放流。stdout
和stderr
内容,并获取退出代码可以不按特定顺序完成,因为检索是异步的。