Как получить статус асинхронной функции до ее завершения? - PullRequest
1 голос
/ 09 октября 2019

Я использую NodeJs execFile () для запуска процесса демона. Я обернул обратный вызов обещанием использовать его асинхронно в других частях моего приложения.

Я понимаю, что обратные вызовы выдают ошибку / результат после завершения. Поэтому при сбое процесса-демона обещание корректно отклоняет ошибку.

Проблема: при правильном запуске процесса-демона обещание ничего не решает, так как обратный вызов еще не завершен,

Ответ получен после остановки процесса демона, поскольку это конец жизненного цикла обратного вызова. Но это слишком поздно.

Вопрос: Как отследить жизненный цикл обратного вызова, чтобы разрешить обещание (callback_in_progress)?

Нужно ли использоватьмодуль событий узла для создания прослушивателя событий?

Это 2 метода из модуля. Первый работает хорошо, но во втором у меня проблема.

const { execFile } = require('child_process');
const path = require('path');
const binaryPath = require('./BinaryPaths')

const mcUtil = path.join(binaryPath, 'multichain-util');
const mcd = path.join(binaryPath, 'multichaind');

module.exports = {
    createChain: (chainName) => {
        return new Promise((resolve, reject) => {
            execFile(mcUtil, ['create', chainName], (err, res) => {
               err ? reject(err) : resolve(res);
            });
        });
    },
    startMultichain: (chainName) => {
        return new Promise((resolve, reject) => {
           execFile(mcd, [chainName, 'daemon'], (err, res) => {
              err ? reject(err.message) : resolve(res);
           });
        });
     },
};

Ответы [ 2 ]

1 голос
/ 09 октября 2019

Вы можете создать оболочку для вашего Обещания , чтобы синхронно получать состояние вашего обещания в вашем коде, например:

class StatefulPromise extends Promise {
  constructor (executor) {
    super((resolve, reject) => executor(
      (val) => {
        resolve(val)
        this._state = 'Resolved'
      },
      (err) => {
        reject(err)
        this._state = 'Rejected'
      },
    ))
    this._state = 'Processing'
  }

  get state () {
    return this._state
  }
}
 
// Create a promise that resolves after 3 sec 
var myStatefulPromise = new StatefulPromise((resolve, reject) => {
  setTimeout(() => resolve(), 3000)
})

// Log the state of above promise every 500ms
setInterval(() => console.log(myStatefulPromise.state), 500)
0 голосов
/ 21 октября 2019

После поиска я нашел решение моей проблемы, опубликованное в другой ветке. Это было довольно просто. Мне нужно было только использовать spawn () вместо execFile (). Это приведет к потоковой передаче данных вместо разрешения только после завершения обратного вызова.

Поток решения здесь: получить execFile stdOut на чанках

...