本文介绍了有条件的Promise.all的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我知道,以下代码基于此。它有效,但我对某些事情不满意。
I'm aware of this answer and the following code is based on it. It is working but I'm not happy with something.
如果我想根据它进行一些条件检查和解决怎么办?我已经评论了我想要更改的代码。
What if I want to make some conditional checking and resolve based on it? I've commented on code where I'd like to change.
/**
* Returns not yet propagate subdomains.
* @return Promise
*/
Tour.prototype.getOffline = function() {
var self = this;
var resolve_, reject_;
// to be fulfilled later
var promise = new Promise(function(resolve, reject){
resolve_ = resolve;
reject_ = reject;
});
var check = function(key) {
return new Promise(function(resolve, reject) {
redis_client.hmget(key, 'online', function(err, reply) {
if (reply[0] === 'n') {
resolve(key); // <----- I'd like to resolve only here
} else {
// reject(); // <---- I can't reject cause of Promise.all
resolve(); // <----- An empty value to satisfy Promise.all
}
});
});
};
this.getKeysRedis('subdomain:*').then(function(resp) {
var promises = resp.map(check);
var results = Promise.all(promises);
results.then(function(data) {
// I have undefined values on data array
var array = data.filter(function(key){
return utils.isDefAndNotNull(key);
});
resolve_(array); // <------ How can I resolve without filtering
});
}, function(error) {
reject_(error);
});
return promise;
};
最终代码,删除 承诺
构造函数反模式作为@Bergi警告:
Final code, removed Promise
constructor antipattern as @Bergi alerted:
Tour.prototype.getOffline = function() {
var self = this;
var check = function(key) {
return new Promise(function(resolve, reject) {
redis_client.hmget(key, 'online', function(err, reply) {
if (reply[0] === 'n') resolve(key);
else reject();
});
});
};
var reflect = function(promise) {
return promise.then(
x => ({state: 'resolved', value: x}),
e => ({state: 'rejected' , value: e})
);
};
return new Promise(function(resolve, reject) {
self.getKeysRedis(self.subdomain_keyname + '*')
.then(function(keys) {
return Promise.all(keys.map(check).map(reflect)).then(function(r) {
return r.filter(x => x.state === 'resolved');
});
})
.then(function(results) {
var array = results.map((result) => result.value);
resolve(array);
})
.catch((err) => reject(err));
});
};
推荐答案
你基本上想要一个承诺并返回的函数在其他承诺结算(履行或拒绝)时履行的承诺:
You basically want a function that takes a promise and returns a promise that fulfills whenever the other promise resolves (fulfills or rejects):
该功能通常称为反映:
function reflect(promise){
return promise.then(x => ({state: "fulfilled", value: x}),
e => ({state: "rejected" , value: e}));
}
这意味着您可以拒绝(像往常一样),然后执行:
This means you can reject (like you normally would) and then do:
this.getKeysRedis('subdomain:*').then(resp =>
resp.map(check).map(reflect); // note the reflect
).then(Promise.all).then(results => {
// access results here
results[0].state; // "fulfilled" if it fulfilled
results[0].value; // the value or error
});
这篇关于有条件的Promise.all的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!