以 Promise.all 为条件 [重复]
Posted
技术标签:
【中文标题】以 Promise.all 为条件 [重复]【英文标题】:Conditional on Promise.all [duplicate] 【发布时间】:2016-02-11 09:10:45 【问题描述】:我知道this answer 并且以下代码基于它。它正在工作,但我对某些事情不满意。
如果我想根据它进行一些条件检查和解析怎么办?我已经评论了我想更改的代码。
/**
* 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;
;
最终代码,删除Promise
构造函数反模式作为@Bergi警告:
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));
);
;
【问题讨论】:
所以你想基本上在所有承诺都完成后执行一个动作,无论是实现还是解决? (如果没有,请edit 包括您正在尝试做的事情,您的目标是什么?) 我想我没有得到你的问题。 避免Promise
constructor antipattern!
【参考方案1】:
你基本上想要一个函数,它接受一个承诺并返回一个承诺,只要另一个承诺解决(履行或拒绝)就履行:
该函数通常称为“反射”:
function reflect(promise)
return promise.then(x => (state: "fulfilled", value: x),
e => (state: "rejected" , value: e));
这意味着您可以拒绝(像往常一样)然后做:
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
);
【讨论】:
这个(x => (state: "fulfilled", value: x)
将如何用javascript 编写?谢谢你的回答。
@JonatasWalker 呃.... 是 JavaScript。它在我假设您正在使用的 Node 上运行 - 它是简短的(箭头)函数语法。在这种情况下,您可以将其替换为 function(x) return state: fulfilled, value: x ;
,但它应该可以工作。以上是关于以 Promise.all 为条件 [重复]的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Promise.all 使用 jest 为多个提取设置测试
如何将 Promise.all() 限制为每秒 5 个 Promise?