【问题标题】:Conditional on Promise.all [duplicate]以 Promise.all 为条件 [重复]
【发布时间】: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 包括您正在尝试做的事情,您的目标是什么?)
  • 我想我没有得到你的问题。

标签: javascript node.js promise


【解决方案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 =&gt; ({state: "fulfilled", value: x}) 将如何用javascript 编写?谢谢你的回答。
  • @JonatasWalker 呃.... JavaScript。它在我假设您正在使用的 Node 上运行 - 它是简短的(箭头)函数语法。在这种情况下,您可以将其替换为 function(x){ return {state: fulfilled, value: x }; },但它应该可以工作。
猜你喜欢
  • 2012-08-05
  • 1970-01-01
  • 1970-01-01
  • 2022-12-01
  • 2017-07-01
  • 2019-06-01
  • 2021-03-22
  • 1970-01-01
  • 2019-05-16
相关资源
最近更新 更多