如何处理Node.js模块中的asynchronouscallback?

这是我第一次试图把一个节点模块放在一起,我仍然试图围绕如何构buildasynchronouscallback。 这是一个例子。 现在我正在尝试使用featureService.getCount()并没有得到任何回应。 使用断点,我知道featureService.getUniqueIds()正在工作。

由于callback在那里,我假设我没有得到一个长度的原因是getCount中的callback尚未响应。 在大部分时间看了下来,并没有真正提出一个非常好的解决scheme,而不是一个recursion循环检查要填充的超时值,我正在寻求build议如何更好地构build我的代码来完成任务在眼前。

我已经读了一些关于承诺。 这是一个适用的实例,甚至是一个可行的解决scheme? 我真的不知道如何实现承诺,但在这种情况下,这是合乎逻辑的。

显然我在这里输了。 感谢您提供的任何帮助。

 var Client = require('node-rest-client').Client; var client = new Client(); var featureService = function(endpoint){ var uniqueIds; var count; // get list of unique id's this.getUniqueIds = function(){ if (!uniqueIds) { var options = { parameters: { f: 'json', where: "OBJECTID LIKE '%'", returnIdsOnly: 'true' } }; client.get(endpoint + '/query', options, function(data, res){ var dataObject = JSON.parse(data); var uniqueIds = dataObject.objectIds; return uniqueIds; }); } else { return uniqueIds; } }; // get feature count this.getCount = function(){ // get uniqueIds uniqueIds = this.getUniqueIds(); // get length of uniqueIds count = uniqueIds.length; }; // get list of unique attribute values in a single field for typeahead this.getTypeaheadJson = function(field){}; // find features in a field with a specific value this.find = function(field, value){}; }; var endpoint = 'http://services.arcgis.com/SgB3dZDkkUxpEHxu/arcgis/rest/services/aw_accesses_20140712b/FeatureServer/1'; var afs = new featureService(endpoint); console.log(afs.getCount()); exports.featureService = featureService; 

现在,在bluebird文档(我不能得到上面的模块工作)的一些更多和使用request ,我有这个工作,但无法弄清楚如何得到计算值的工作,数迭代。

 var Promise = require("bluebird"), request = Promise.promisifyAll(require("request")); var FeatureService = function(){ // get count from rest endpoint var getCount = function(){ var optionsCount = { url: endpoint + '/query', qs: { f: 'json', where: "OBJECTID LIKE '%'", returnCountOnly: 'true' } }; return request.getAsync(optionsCount) .get(1) .then(JSON.parse) .get('count'); }; // get max record count for each call to rest endpoint var getMaxRecordCount = function(){ var optionsCount = { url: endpoint, qs: { f: 'json' } }; return request.getAsync(optionsCount) .get(1) .then(JSON.parse) .get('maxRecordCount'); }; // divide the total record count by the number of records returned per query to get the number of query iterations this.getQueryIterations = function(){ getCount().then(function(count){ getMaxRecordCount().then(function(maxCount){ return Math.ceil(count/maxCount); }); }); }; }; // url to test against var endpoint = 'http://services.arcgis.com/SgB3dZDkkUxpEHxu/arcgis/rest/services/aw_accesses_20140712b/FeatureServer/1'; // create new feature service object instance afs = new FeatureService(); // This seems like it should work, but only returns undefined console.log(afs.getQueryIterations()); // this throws an error telling me "TypeError: Cannot call method 'then' of undefined" //afs.getQueryIterations().then(function(iterCount){ // console.log(iterCount); //}); 

是的,使用承诺! 他们是一个强大的工具 ,正是为了这个目的而devise的,而且一个体面的库很容易使用。 在你的情况下:

 var Promise = require('bluebird'); // for example, the Bluebird libary var Client = Promise.promisifyAll(require('node-rest-client').Client); var client = new Client(); function FeatureService(endpoint) { var uniqueIds; var count; // get list of unique id's this.getUniqueIds = function(){ if (!uniqueIds) { // by caching the promise itself, you won't do multiple requests // even if the method is called again before the first returns uniqueIds = client.getAsync(endpoint + '/query', { parameters: { f: 'json', where: "OBJECTID LIKE '%'", returnIdsOnly: 'true' } }) .then(JSON.parse) .get("objectIds"); } return uniqueIds; }; // get feature count this.getCount = function(){ if (!count) count = this.getUniqueIds() // returns a promise now! .get("length"); return count; // return a promise for the length }; // get list of unique attribute values in a single field for typeahead this.getTypeaheadJson = function(field){}; // find features in a field with a specific value this.find = function(field, value){}; }; var endpoint = 'http://services.arcgis.com/SgB3dZDkkUxpEHxu/arcgis/rest/services/aw_accesses_20140712b/FeatureServer/1'; var afs = new FeatureService(endpoint); afs.getCount().then(function(count) { console.log(count); }); // you will need to use a callback to do something with async results (always!) exports.FeatureService = FeatureService; 

在这里,使用蓝鸟的Promise.promisifyAll ,你可以使用.getAsync()而不是.get() ,并将得到一个承诺的结果。


 // divide the total record count by the number of records returned per query to get the number of query iterations this.getQueryIterations = function(){ getCount().then(function(count){ getMaxRecordCount().then(function(maxCount){ return Math.ceil(count/maxCount); }); }); }; 

这是正确的主意! 只有你总是想从.then处理程序return一些东西,这样.then()调用返回的promise将会以该值来parsing。

 // divide the total record count by the number of records returned per query to get the number of query iterations this.getQueryIterations = function(){ return getCount().then(function(count){ // ^^^^^^ return the promise from the `getQueryIterations` method return getMaxRecordCount().then(function(maxCount){ // ^^^^^^ return the promise for the iteration number return Math.ceil(count/maxCount); }); }); }; 

现在,你回到了最内在的结果的承诺,现在这将工作:

 afs.getQueryIterations().then(function(iterCount){ console.log(iterCount); });