【问题标题】:Nodejs - SolrClient, how to wait for responseNodejs - SolrClient,如何等待响应
【发布时间】:2014-12-21 09:22:16
【问题描述】:

我有一个关于 nodejs 的 solr-client 模块的问题。我正在使用这个模块来查询 solr-index。

只要我不必等待查询完成并且我只需要异步结果的结果,模块本身就可以正常工作。

但目前我不知道如何才能等待搜索请求完成并按顺序使用结果。

我的经理有以下方法

SolrManager.prototype.promisedQuery = function(query, callback) {
var solrClient = solr.createClient(this.configuration.cores.page);

var docs = null;
var finished = false;
var deferred = Q.defer();

var request = solrClient.search(query, function(err,obj){
    if (!err) {
        if (obj.response.numFound > 0) {
            deferred.resolve(obj.response.docs);
        } else {
            deferred.resolve(null);
        }
    } else {
        deferred.reject(err);
    }
});

var records = null;
var promise = deferred.promise;
promise.then(function(result) {
    records = result;
}).fail(function(error){
    records = error;
});

return records;

};

这里的问题是,我尝试等待查询结果并将其用作“promisedQuery”的返回值。

我从几天前开始尝试在顺序调用中使用此方法,还使用不同的附加模块,如“wait.for”、“q”等,但似乎没有任何效果。

solr-client 的回调函数总是在 manager-method 已经返回后执行。同样,promise-methods 甚至会在 manager-method 返回后被调用。

有人可以在该主题上帮助我或提供一些提示,我如何等待 solr-client-search 操作的响应,然后按顺序返回?

感谢您的帮助。

乌多·格哈兹

【问题讨论】:

    标签: javascript node.js asynchronous solr client


    【解决方案1】:

    一个多星期,现在看来我找到了解决办法:

    SolrManager.prototype.promisedQuery = function(query, callback) {
    var solrClient = solr.createClient(this.configuration.cores.page);
    
    var docs = null;
    var deferred = Q.defer();
    
    var request = solrClient.search(query, function(err,obj){
        if (!err) {
            if (obj.response.numFound > 0) {
                deferred.resolve(obj.response.docs);
            } else {
                deferred.resolve(null);
            }
        } else {
            deferred.reject(err);
        }
      });
    
    return deferred.promise;
    };
    

    在调用上述函数的所有其他管理器中:

    ...
    var dbPromise = this.solrManager.promisedQuery(query);
    
    var _self = this;
    return Q.async(function*(){
        var result = yield dbPromise;
        return result;
    });
    ...
    

    在第一次测试之后,同步方法似乎会等到承诺完成。

    唯一的一点是,它仅在 NodeJs 版本 0.11.10 上运行,该版本支持生成器功能,并带有激活的 --harmony-flag 和“q”-module。

    最好的问候

    乌多

    【讨论】:

      【解决方案2】:

      您只是使用了一些不正确的承诺。您需要返回“deferred.promise”,而不是返回记录。它应该看起来像这样(请注意,您不需要传递给 promiseQuery 的回调)。

      SolrManager.prototype.promisedQuery = function(query) {
          var solrClient = solr.createClient(this.configuration.cores.page),
          deferred = Q.defer();
      
          solrClient.search(query, function(err,obj){
              if (!err) {
                  if (obj.response.numFound > 0) {
                      deferred.resolve(obj.response.docs);
                  } else {
                      deferred.resolve(null);
                  }
              } else {
                  deferred.reject(err);
              }
          });
      
          return deferred.promise;
      };
      

      要使用它,您可以执行以下操作:

      SolrManager.promisedQuery(myquery)
          .then(function (data) {
              // data is whatever your 'resolved' in promisedQuery
          }, function (err) {
              // err is whatever you rejected in promisedQuery
          });
      

      【讨论】:

      • 你好 rquinn,是的,我知道。我也试过直接返回promise,但是结果是一样的,只是在调用方法中。例如我从改编的“valueOf”方法中调用“promisedQuery”。我目前不知道如何在“valueOf”方法中正确处理承诺以从数据库返回结果。上面的代码是我的一次尝试的快照。 :)
      • 您在示例中没有正确返回承诺。这就是为什么你没有得到价值,我想。
      • 是的,你是对的!我现在已根据您的建议对其进行了更改。请看下面它现在的样子! :)
      • 我很高兴它现在正在工作。我不确定在哪里可以看到您的更改?也许您可以编辑您的问题并在最后添加您为修复它所做的事情?哦,没关系,我现在看到了。
      • 见下文。我添加了改编版本来澄清我的问题......具体来说,我想覆盖自定义对象的“toString”和“valueOf”方法,以将其内容作为字符串返回。并且对象的值应该包含来自数据库的部分结果。
      【解决方案3】:

      根据 rquinns 的回答,我已将代码更改如下:

      SolrManager.prototype.promisedQuery = function(query, callback) {
      var solrClient = solr.createClient(this.configuration.cores.page);
      
      var docs = null;
      var finished = false;
      var deferred = Q.defer();
      
      var request = solrClient.search(query, function(err,obj){
          if (!err) {
              if (obj.response.numFound > 0) {
                  deferred.resolve(obj.response.docs);
              } else {
                  deferred.resolve(null);
              }
          } else {
              deferred.reject(err);
          }
      });
      
      return deferred.promise;
      };
      
      ...
      
      DemoObject.prototype.toString = function() {
       return SolrManager.promisedQuery(this.query).then(function(result){
         return result['title'];
       }).fail(function(error){
         return error;
       });
      };
      
      DemoObject.prototype.typeOf = function() {
       return SolrManager.promisedQuery(this.query).then(function(result){
         return result['title'];
       }).fail(function(error){
         return error;
       });
      };
      

      我认为,这是使用“承诺”对象的正确方法。但是当我执行以下操作时会发生什么:

      ...
      var demoObject = new DemoObject();
      demoObject.query = "id:1";
      console.log(''+demoObject);
      ...
      

      或者如果我通过将“demoObject”连接到一个字符串来使用它

      ...
      var string = "Some string "+demoObject;
      ...
      

      在字符串连接的情况下,我目前不确定该字符串是否还包含数据库中的标题字段。控制台输出相同。

      nodejs 是否会如此智能以至于它可以解析例如数据库结果“之后”的字符串连接将可用?

      BR

      乌多

      【讨论】:

      • 我认为这是一个坏主意,因为您现在正在制作 toString 和 typeOf 异步方法。要记录 toString 的结果,您必须执行类似 demoObject.toString().then(function (data) { console.log(data);})
      • 是的,这正是我的问题!我想处理同步方法中异步方法的结果。当我将“demoObject”添加到字符串时,我还想返回索引结果。在我的代码中,由于使用这些对象的目标,除了覆盖这两种方法之外没有其他机会。是否有机会,我可以在这些方法中等待,直到提供索引的结果?我尝试了不同的东西,比如“setTimeout”、控制循环、其他模块等,但没有任何效果。也许你有一些建议,我如何等待索引的结果。
      • 如果没有,也许这也可能是对 solr-client-module 程序员在客户端上提供一些同步方法的建议。
      • promises 是做到这一点的方法。承诺的重点是让您以类似同步的方式编写代码,用于异步代码。我不确定你为什么要强制同步行为,但也许这会有所帮助:stackoverflow.com/questions/21819858/…
      • 整个编程都是特定 vm 上下文的一部分,我想在其中使用这些对象作为全局对象,这些对象应该在上下文对象本身上进行交换。在评估在 vm 中运行的代码之后,这些对象应该通过上下文对象交换到“正常”编程。具体来说,我想像在普通的 javascript 编程中一样在 vm 中创建全局对象,然后在我的 nodejs 代码中使用它们。然后这些对象将,例如在模板引擎中用于生成输出。
      猜你喜欢
      • 1970-01-01
      • 2018-08-04
      • 2016-04-30
      • 2022-07-01
      • 2018-11-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-14
      相关资源
      最近更新 更多