node.js - 在 NodeJS 中承诺混淆
问题描述
我在思考 NodeJS 上代码执行的异步特性时遇到了很多麻烦。我有一个简单的函数来获取ip a
Linux 机器上的输出并手动解析 IP 子网。完成后,我只想访问console.log()
IP 子网。
我知道 NodeJS 主要是异步运行的,所以我不能指望在console.log()
变量之前完成逻辑。我了解回调的概念来解决这个问题,但我更愿意访问逻辑循环之外的变量。我求助于 Promises,这似乎是一个很好的解决方案,但我认为我遗漏了一些东西,而且它们没有按我预期的方式工作。下面是我的代码:
let subnetString = '';
function getIPLinux() {
return new Promise((resolve) => {
const ipOutput = spawn( 'ip', ['a'] );
ipOutput.stdout.on('data', (data) => {
String(data).split('\n').forEach( (line) => {
if ( line.includes('inet') && line.indexOf('inet6') < 0 && line.indexOf('127.0.0.1') < 0 ) {
const ipSubnet = line.split(' ')[5];
const ipStringArray = ipSubnet.split('.');
subnetString = ipStringArray[0] + '.' + ipStringArray[1] + '.' + ipStringArray[2] + '.*';
console.log('Found subnet at end of if loop: ' + subnetString);
}
})
})
console.log('Found subnet at end of promise: ' + subnetString);
resolve();
})
}
getIPLinux().then( () => {
console.log('Found subnet after then: ' + subnetString);
});
我的输出如下:
Found subnet at end of promise:
Found subnet after then:
Found subnet at end of if loop: 192.168.1.*
只有记录的最后一行是正确的。我无法将注意力集中在这种非阻塞代码执行上。如果我以错误的方式来,我也对其他方法持开放态度。
解决方案
spawn() 也是异步的。您正在为 stdout 使用事件回调,这很好,但您正在立即解决低于该承诺的承诺,而无需等待输入完成。尝试
ipOutput.on('close', () => {
console.log('Found subnet at end of promise: ' + subnetString);
resolve(subnetString);
});
在你的承诺结束时。
https://nodejs.org/api/child_process.html#child_process_event_close
推荐阅读
- python - 我如何读取文件的十六进制内容并将其写入十六进制文件
- unit-testing - How to test ListenableFuture Callbacks in spock
- arrays - 如何附加到 [[String : [String]]] = [[:]] 而不是 [String : [String]] = [:]?
- javascript - Chrome 扩展程序可以公开虚拟相机并对其进行渲染吗?
- ios - 静默推送通知不适用于前台 iOS 应用程序
- javascript - 我不知道我的 javascript 文件是否没有收到 json 或者我的驱动程序没有发送它们?
- microsoft-graph-api - Microsoft Graph Api 更新文件版本号
- perl - 在不同 perl 版本下运行的程序之间传递对象
- scala - 将简单值从 Map 映射到 spark DataFrame 错误
- airflow - 带有 PapermillOperator 的 Airflow 中的“错误 - 无法编译非模板节点”是什么意思?