Nodejs Promise.all() 总是解析
Nodejs Promise.all() resolving always
我是新手。我正在尝试 ping 一些机器以检查它们是否处于活动状态。我正在使用本机 NodeJS 承诺。我的 ping 功能:
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
解决方案
要解决此问题,请在 catch
处理程序中再次抛出错误,如下所示
}).catch(function (err) {
console.log(err);
throw err;
});
或删除 catch
处理程序。基本上,您应该让拒绝沿着链条向下流动,以便 Promise.all
在机器停机时得到拒绝的承诺。
基本认识
所有 then
和 catch
处理程序创建一个新的 Promise 对象并 return 它们,以便我们可以链接它们。
当 Promise 被拒绝时,拒绝处理程序将处理它,但如果拒绝处理程序不拒绝承诺,则链中的后续处理程序不会将承诺视为已拒绝.
在你的情况下,当机器停机时,你拒绝它并且拒绝被处理,
}).catch(function (err) {
console.log(err);
});
但是,catch
处理程序 return 是一个未被拒绝的承诺。所以,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")
});
我是新手。我正在尝试 ping 一些机器以检查它们是否处于活动状态。我正在使用本机 NodeJS 承诺。我的 ping 功能:
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
解决方案
要解决此问题,请在 catch
处理程序中再次抛出错误,如下所示
}).catch(function (err) {
console.log(err);
throw err;
});
或删除 catch
处理程序。基本上,您应该让拒绝沿着链条向下流动,以便 Promise.all
在机器停机时得到拒绝的承诺。
基本认识
所有
then
和catch
处理程序创建一个新的 Promise 对象并 return 它们,以便我们可以链接它们。当 Promise 被拒绝时,拒绝处理程序将处理它,但如果拒绝处理程序不拒绝承诺,则链中的后续处理程序不会将承诺视为已拒绝.
在你的情况下,当机器停机时,你拒绝它并且拒绝被处理,
}).catch(function (err) {
console.log(err);
});
但是,catch
处理程序 return 是一个未被拒绝的承诺。所以,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")
});