Nodejs Promise.all()总是parsing

我对承诺是新的。 我正在尝试ping一些机器来检查它们是否处于活动状态。 我正在使用本地NodeJS承诺。 我的pingfunction:

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!")}); }); 

现在,即使某个节点closures,它也不会拒绝:

 [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 

为了解决这个问题,像这样在catch处理程序中再次抛出错误

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

或删除catch处理程序。 基本上,你应该让拒绝stream下来,所以,如果一台机器停机, Promise.all会得到拒绝的承诺。


基本的理解

  1. then所有的catch处理程序创build一个新的Promise对象并返回它们,以便我们可以链接它们。

  2. 当一个Promise被拒绝时,一个拒绝处理器会处理它,但是如果拒绝处理器没有拒绝承诺,那么链中的后续处理器将不会将该承诺视为被拒绝。

在你的情况下,当机器停机时,你拒绝它,拒绝处理,

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

但是, catch处理程序返回一个不被拒绝的promise。 所以, 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") });