首页 > 解决方案 > 在 NodeJS 中承诺混淆

问题描述

我在思考 NodeJS 上代码执行的异步特性时遇到了很多麻烦。我有一个简单的函数来获取ip aLinux 机器上的输出并手动解析 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.*

只有记录的最后一行是正确的。我无法将注意力集中在这种非阻塞代码执行上。如果我以错误的方式来,我也对其他方法持开放态度。

标签: node.jsjavascript

解决方案


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


推荐阅读