2015-06-10 3 views
4

Я новичок в обещаниях. Я пытаюсь выполнить ping некоторые машины, чтобы проверить, являются ли они активными. Я использую собственные обещания NodeJS. Моя функция пинг:Nodejs Promise.all() всегда разрешает

function ping(addr) { 
    return new Promise(function(resolve, reject) { 
     var args = ['-n', '1', '-w', '5000']; 
     args.push(addr); 
     var ls = cp.spawn('ping.exe', args); 

     ls.on('error', function (e) { 
      reject(Error('There was an error while executing the ping')); 

     }); 

     ls.on('exit', function (code) { 
      if(code === 0) { 
       resolve({host: addr}); 
      } 
      else { 
       reject(Error(addr + " is down!")); 
      } 

     }); 
    }); 

} 

Теперь у меня есть детали машин в массиве чтения из JSON:

gulp.task('pingNodes', ['readConfigJSON'], function() { 

    var batches = ConfigJSON.NodeDetails.Batch1.concat(ConfigJSON.NodeDetails.Batch2); 
    var pingPromises = batches.map(function (host) { 
     return ping(host.Name) 
      .then(function (res) { 
       console.log(res.host + " is up!"); 
      }).catch(function (err) { 
       console.log(err); 
      }); 
    }); 
    return Promise.all(pingPromises).then(function(){console.log("All nodes are up!")}); 
}); 

Теперь не отвергает даже если какой-то узел вниз:

[16:58:46] Starting 'init'... 
Starting Deployment 
[16:58:46] Finished 'init' after 135 µs 
[16:58:46] Starting 'readConfigJSON'... 
[16:58:46] Finished 'readConfigJSON' after 204 µs 
[16:58:46] Starting 'pingNodes'... 
machine1 is up! 
machine2 is up! 
machine3 is up! 
[Error: machine4 is down!] 
All nodes are up! 
[16:58:49] Finished 'pingNodes' after 2.54 s 

ответ

5

Решение

Чтобы устранить эту проблему, бросить эр ROR снова в catch обработчике, как это

}).catch(function (err) { 
    console.log(err); 
    throw err; 
}); 

или удалить catch обработчик. В принципе, вы должны позволить отказу течь по цепочке, так что Promise.all получает отклоненное обещание, если машина выключена.


Основные пониманий

  1. Все then и catch обработчики создать новый объект Promise и вернуть их, так что мы можем приковать их.

  2. Когда обещание отклонено, обработчик отклонения будет обрабатывать его, но если обработчик отклонения не отклонит обещание, то последующий обработчик в цепочке не будет рассматривать обещание как отклоненное.

В вашем случае, когда аппарат выключен, вы отвергаете его и отказ обрабатывается,

}).catch(function (err) { 
    console.log(err); 
}); 

Но, то catch обработчик возвращает обещание, которое является не отвергается. Итак, Promise.all фактически получает объект Promise, который не отклоняется. Вот почему он не останавливается, как только выясняется, что одна из машин выключена.

Вы можете подтвердить это понимание со следующей программой

var a = Promise.resolve(1) 
    .then(function (e) { 
     throw e; 
    }) 
    .catch(function (e) { 
     // This is what you are doing if the machine is down 
     console.log(e); 

     // No rejection here, so `then` will be called. 
     // Uncomment the throw to see 
     // throw e; 
    }); 

a.then(function (e) { 
    console.log("Inside then") 
}); 

a.catch(function (e) { 
    console.log("Inside catch") 
}); 

+0

Спасибо! так что либо я должен удалить catch, либо если я обработаю отклонение в catch, мне нужно выбросить ошибку. –

+0

@adnankamili Точно :-) В принципе, вы должны позволить отказу течь по цепочке. – thefourtheye

Смежные вопросы