Javascript Nodejs-SolrClient,如何等待响应

Javascript Nodejs-SolrClient,如何等待响应,javascript,node.js,asynchronous,solr,client,Javascript,Node.js,Asynchronous,Solr,Client,我有一个关于nodejs的solr客户端模块的问题。我使用这个模块来查询solr索引 只要我不必等待查询完成,并且只需要将结果作为异步结果,模块本身就可以正常工作 但目前我还不知道,我如何才能等待搜索请求的完成并按顺序使用结果 我的经理有以下方法 SolrManager.prototype.promisedQuery = function(query, callback) { var solrClient = solr.createClient(this.configuration.cores.

我有一个关于nodejs的solr客户端模块的问题。我使用这个模块来查询solr索引

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

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

我的经理有以下方法

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客户端的回调函数将始终在manager方法返回后执行。此外,还会在manager方法返回后调用promise方法

有人能帮我解决这个问题吗?或者有一些提示,我如何等待solr客户端搜索操作的响应,然后按顺序返回

谢谢你的帮助


乌多·格哈德斯(Udo Gerhards)

你只是有点不正确地使用了承诺。您需要返回“deferred.promise”,而不是返回记录。它应该是这样的(注意,您不需要传入promisedQuery的回调)

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

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

根据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;
...
在字符串连接的情况下,我目前不确定字符串是否也包含数据库中的title字段。控制台输出也是如此

nodejs是否会如此智能,以至于它能够解析例如“之后”的字符串连接,从而获得来自数据库的结果


Udo

一周多以来,我似乎找到了一个解决方案:

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标志和“q”模块

致意


Udo

你好,rquinn,是的,我知道。我还试图直接返回承诺,但结果是相同的,只是在调用方法中。例如,我从一个经过修改的“valueOf”-方法调用“promisedQuery”。我目前不知道如何在“valueOf”方法中正确处理从数据库返回结果的承诺。上面的代码是我的一次尝试的快照。:)在您的示例中,您没有正确地返回承诺。我想这就是为什么你没有得到价值。是的,你是对的!我现在已经改成你的建议了。请看下面它现在的样子!:)我很高兴它现在起作用了。我不知道在哪里可以看到您的更改?也许你可以编辑你的问题,并在最后添加你所做的修改?哦,没关系,我现在看到了。看下面。我添加了改编版本来澄清我的问题。。。具体地说,我想重写自定义对象的“toString”和“valueOf”方法,将其内容作为字符串返回。对象的值应该包含在数据库的部分结果中。我认为这是一个坏主意,因为您现在正在创建toString和typeOf异步方法。要记录toString的结果,必须执行类似demoObject.toString()的操作。然后(函数(数据){console.log(数据);})是的,这正是我的问题!我想在同步方法中处理异步方法的结果。当我将“demoObject”添加到字符串中时,我还希望返回索引结果。在我的代码中,由于这些对象的使用目标,除了重写这两个方法之外没有其他机会。我是否有可能在这些方法中等待,直到索引的结果被提供?我尝试了不同的方法,比如“setTimeout”,控制循环,其他模块等等,但都没用。也许你有一些建议,我可以如何等待索引的结果。如果没有,也许这也可以建议solr客户端模块程序员在客户端提供一些同步方法。承诺是实现这一点的方法。承诺的要点是让您以类似同步的方式编写代码,用于异步代码。我不确定您为什么要强制执行同步行为,但这可能会有所帮助:整个程序都是特定vm上下文的一部分,我想在其中使用这些对象作为全局对象,这些对象应该通过上下文对象本身进行交换。在评估vm中运行的代码之后,这些对象应该通过上下文对象交换到“普通”程序。具体地说,我希望像在普通javascript编程中一样在vm中创建全局对象,然后在我的nodejs代码中使用它们。例如,这些对象将在模板引擎中用于生成输出。
...
var dbPromise = this.solrManager.promisedQuery(query);

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