Подтвердить что ты не робот

Прекратить выполнение процессов после отклонения обещания

Я использую следующий код, который работает нормально, но проблема в том, что когда я получаю сообщение об ошибке, я хочу, чтобы он остановил все остальные promises. Например, если chi.getCommand(val1, val2), отправит отклонение, и я попал в catch catch, я хочу отменить promises для chss.exe и app.getStatus(12); Как я могу это достичь?

  var start = Promise.all([
      chi.getCommand(val1, val2),
      chi.findAndUpdateCustomer()
    ]).spread(function (command, customer) {
        return chss.exe(runnableDoc, command, customer)
                 .delay(10)
                 .then(function (val) {
                   if (val) console.log(val);
                   return app.getStatus(12);
                 });
    }).catch(function (err) {
        // catch and handle errors and when it come to here I want it to stops all the chain above
    });

Это короткий код команды get:

function getCommand(method, cmd) {
  return new Promise(function (resolve, reject) {
    ...
    child.stderr.on('data', function (data) {
        console.log('stderr: here!' + data);
        reject(data);
    });
}

Откроется журнал консоли stderr: here!, чтобы вызвать вызов!

Update1

Единственное, что останавливает getStatus, это когда я помещаю process.exit(1) Но это убивает весь процесс, я просто хочу остановить всю цепочку функции getCommand в случае, если Im прибывает в блок catch,

  • Есть ли способ?
  • Это ошибка в blueBird? Я использую "синюю птицу": "2.9.34"

функция getCommand (метод, cmd) {     return new Promise (функция (разрешение, отклонение) {

var spawn = require('child_process').spawn;
var ls = spawn("cmdbug",["/c","npm install express --save"]);


    ls.on('error', function (err) {
        console.log(err);
        reject(err);
    });

ошибка, которую я получил, это

{[Ошибка: spawn cmdr ENOENT]   код: "ENOENT",   errno: ENOENT,   syscall: 'spawn cmdbug',   path: 'cmdr',   spawnargs: ['/g', 'npm install express --save']} {[Ошибка: вызвать cmdbug ENOENT]   код: "ENOENT",   errno: ENOENT,   syscall: 'spawn cmdbug',   path: 'cmdr',   spawnargs: ['/g', 'npm install express --save']} Не удалось выполнить дочерний процесс с кодом -4058

И все же процесс getStatus записывает на консоль.

Код, который я использую, а не для тестирования:

getCommand - это функция, которая выдает ошибку !

var start= function () {
    return new Promise.all([
        childP.getChildProcessCommand(val1, val2),
        childP.findAndUpdateCustomer()
    ]).spread(function (cmd, updated) {
            //Execute child process
            return Promise.all([
                childP.getCommand('spawn', cmd),
                app.getStatus(51000,10,1);
            ]).catch(function (err) {
                // catch and handle errors
                console.log("An error occur: " + err);
                return;
            })
        }).catch(function (err) {
            // catch and handle errors
            console.log("An error occur: " + err);
            return;
        })
}();

Код для статуса проверки:

// Returns a promise that resolves when the port is open

checkPortStatus: function(port, host){
  return new Promise((resolve, reject) => {
    portscanner.checkPortStatus(port, host, function(error, status) {
      if(error)
        reject(error);
      else if(status === 'open')
        resolve(status);
      else
        reject(new Error('Port is not open'));
    });
  });
},

// THE API function
getStatus: function(port, retriesLeft) {

  const TIME_BETWEEN_CHECKS = 1000;
  const HOST = '127.0.0.1';
  const RETRIES = 20;
  retriesLeft = retriesLeft === void 0 ? RETRIES : retriesLeft;

  if(!port) throw new Error('Port is required');
  if(retriesLeft === 0) Promise.reject('Timed Out');

  return new Promise((resolve, reject) => {

    // If it rejects, we do added work.
    this.checkPortStatus(port, host).then(resolve, error => {
     console.log("Waiting for port " + port + " attempt: " + retry);
      setTimeout(() => {

        this.getStatus(port, retriesLeft - 1).then(resolve, reject);

      }, TIME_BETWEEN_CHECKS);
    });
  });
}

И я вижу ошибку в консоли и все еще вижу консольный журнал для 10 попыток. console.log( "Ожидание порта" + порт + "попытка:" + повторить попытку);

UPDATE2 При попытке изменить Как @artur предложите во втором варианте, я получил ошибку при повторном вызове:

TypeError: Невозможно прочитать свойство 'then' из undefined

Вот что я пробовал:

getStatus: function(port, retriesLeft) {

  const TIME_BETWEEN_CHECKS = 1000;
  const HOST = '127.0.0.1';
  const RETRIES = 20;
  retriesLeft = retriesLeft === void 0 ? RETRIES : retriesLeft;

  if(!port) throw new Error('Port is required');
  if(retriesLeft === 0) Promise.reject('Timed Out');

  var promise = new Promise((resolve, reject) => {

    // If it rejects, we do added work.
    this.checkPortStatus(port, host).then(resolve, error => {
     console.log("Waiting for port " + port + " attempt: " + retry);
      setTimeout(() => {
        //The error in the following recursive call
        this.getStatus(port, retriesLeft - 1).then(resolve, reject);

      }, TIME_BETWEEN_CHECKS);
      }).catch(function (error) {
         return reject(error);
     });
        return {
            promise:promise,
    cancel: function() {
        console.log('cancelling');
        clearTimeout(token);
        }

       }
    });
  });
}
4b9b3361

Ответ 1

Как отметил @Esailija, bluebird имеет встроенный механизм отмены, который действительно хорош и, безусловно, полностью отлично для простых вычислений async.

Promise.config({
  cancellation: true
});

function createCancellableMock(result, time) {

  return new Promise(function(resolve, reject, onCancel) {

    // var child = runCommand();
    var token = setTimeout(function() {
      if (result) {
        console.log('almost done', result);
        resolve(result);
      } else {
        reject('_ERR_');
      }
    }, time);

    onCancel(function() {
      console.log('cancelling');
      // child.kill('SIGTERM');
      clearTimeout(token);
    })
  })

}

var op1 = createCancellableMock('ok-1', 1000);
//var op2 = createCancellableMock('ok-2', 500);
var op2 = createCancellableMock(null, 500); // will be rejected

Promise.all([op1, op2])
  .spread(function(v1, v2) {
    console.log('BOTH-OK', v1, v2)
  })
  .catch(function() {
    console.error('ERROR');
    op1.cancel();
  })
  .finally(function() {
    console.log('finally');
  })
<script src="https://cdnjs.cloudflare.com/ajax/libs/bluebird/3.3.0/bluebird.core.js"></script>

Ответ 2

Ну, в вашем фактическом коде (том из UPDATE1) вы выполняете getCommand одновременно с getStatus, а не в последовательности. Вы вызываете (запускаете) оба из них до того, как дочерний процесс выходит из строя, а когда он делает, ничего не остановит getStatus.

Просто соедините их вместе, как в первом фрагменте, где отказ в getCommand приведет к тому, что getStatus не будет запущен вообще. Вы можете использовать

childP.getCommand('spawn', cmd)
.timeout(5000)
.then(function(cmdresult) {
    return app.getStatus(51000, 10, 1);
}).catch(function (err) {
    console.log("An error occured: " + err);
});