gpt4 book ai didi

javascript - 如何处理 Node.js 模块中的异步回调?

转载 作者:行者123 更新时间:2023-11-30 17:20:20 25 4
gpt4 key购买 nike

这是我第一次尝试将 Node 模块放在一起,我仍在努力思考如何构建异步回调。这是一个很好的例子。现在我正在尝试使用 featureService.getCount() 并且没有得到任何响应。使用断点,我知道 featureService.getUniqueIds() 正在工作。

由于回调在那里,我假设我没有得到长度的原因是 getCount 中的回调尚未响应。在看了一个下午的大部分时间之后,除了递归循环检查要用超时填充的值之外,并没有真正提出一个很好的解决方案,我正在寻求建议如何更好地构建我的代码来完成任务就在眼前。

我读过一些关于 promises 的内容。这是一个适用的实例,甚至是一个可行的解决方案?我真的不知道如何实现 promise ,但在这种情况下它是合乎逻辑的。

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

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);
//});

最佳答案

是的,使用 promise !他们是powerful tool ,正是为此目的而制作的,并带有 decent library它们易于使用。在你的情况下:

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;

在这里,使用 Bluebird's Promise.promisifyAll ,您可以只使用 .getAsync() 而不是 .get(),并且会得到对结果的 promise 。


// 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处理程序返回一些东西,这样.then()返回的promise > 调用将以该值解析。

// 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);
});
});
};

现在,你得到一个 promise for the innermost result ,这现在可以工作了:

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

关于javascript - 如何处理 Node.js 模块中的异步回调?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25253279/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com