循环异步运行节点子进程,并在循环结束后接收stdout结果

问题描述 投票:0回答:1

我有以下示例代码...

const { exec } = require('child_process');

const Main = async () => {
    const ret = await GetAllItems();

    console.log('results', ret);
};

const GetAllItems = async () => {
    const promises = [];

    for (let i = 0; i < 15; i++) {
        promises.push(GetItem(i));
    }

        console.log('=== Loop ended ===')

    return await Promise.all(promises).then((values) => {
        return values;
    });
};

const GetItem = async (item = '') => {
    console.log('Getting data:', item);

    return new Promise((resolve, reject) => {
        exec('echo', [item], (error, stdout, stderr) => {
            if (error) {
                throw error;
            }
            // console.log(stdout);
            console.log('Receiving Data: ' + item);
            resolve('Receiving Data: ' + item);
        });
    });
};

Main();

这就是我得到的结果...

Getting data: 0
Getting data: 1
Getting data: 2
Getting data: 3
Getting data: 4
Getting data: 5
Getting data: 6
Getting data: 7
Getting data: 8
Getting data: 9
Getting data: 10
Getting data: 11
Getting data: 12
Getting data: 13
Getting data: 14
=== Loop ended ===
Receiving Data: 12
Receiving Data: 11
Receiving Data: 10
Receiving Data: 9
Receiving Data: 8
Receiving Data: 7
Receiving Data: 6
Receiving Data: 5
Receiving Data: 4
Receiving Data: 3
Receiving Data: 2
Receiving Data: 1
Receiving Data: 0
Receiving Data: 14
Receiving Data: 13

所以我的问题是,为什么我只有在循环结束后才收到数据?知道为什么要按这个特定顺序吗?

理想情况下,我希望在命令执行后(循环结束之前)立即接收数据,这可能吗?

感谢您的帮助!

======================

javascript node.js asynchronous stdout child-process
1个回答
0
投票
class ItemGetter extends EventEmitter {
  constructor() {
    super();
    this.on('item', item => this.handleItem(item));
  }

  handleItem(item) {
    console.log('Receiving Data: ' + item);
  }

  getAllItems () => {
    for (let i = 0; i < 15; i++) {
      GetItem(i).then(item => this.emit('item', item));
    }
    console.log('=== Loop ended ===')
  };

  async getItem (item = '') {
    console.log('Getting data:', item);
    return new Promise((resolve, reject) => {
      exec('echo', [item], (error, stdout, stderr) => {
        if (error) {
          throw error;
        }
        resolve('Receiving Data: ' + item);
      });
    });
  }
}

(new ItemGetter()).getAllItems()

您的逻辑是,首先,运行循环调用所有 GetItem,然后输出 '=== 循环结束 ===',并且只有在此之后才运行所有 promices 解析,因此,如果您希望彼此独立地获取每个 getItem 执行的结果,只是不要滥用异步逻辑,通常正确的解决方案比看起来更简单;)

© www.soinside.com 2019 - 2024. All rights reserved.