Sails.js 控制器等待异步服务方法
Sails.js controller waits for async service method
我不太习惯 nodejs/javascript 中的 Promises,基本上我希望我的控制器 return 只有在我的 promise 完成后才给一个值 运行。
我的 Sails 应用程序中有以下服务。我正在使用请求承诺模块向 facebook 图 api.
发出 HTTP 请求
return http(options).then(function(data){
var res = JSON.parse(data);
if(!res || res.error) {
console.log(!res ? 'error occurred while loading photos' : res.error);
return;
}
for (var photoIndex in res.data) {
var photo = res.data[photoIndex];
if (photo.tags) {
for(var tagIndex in photo.tags.data){
var tag = photo.tags.data[tagIndex];
console.log('TAG_ID: '+tag.id + ' -> TARGET_ID: ' + target);
if (tag.id == target) {
photos.push(photo);
}
}
}
}
if (res.paging && res.paging.next) {
console.log('recursion in action!!');
myself(id, target, accessToken, decodeURIComponent(res.paging.next));
}
我的控制器是:
var countPhotos = Facebook.countTaggedPhotos(requesterId, targetId, accessToken).then(function(photos){
return res.json({photos: photos.length});
});
但是控制器在我的服务承诺结束之前 returning 0,当我查看日志时我可以看到它仍在执行循环。
如何让我的控制器在 return 之前等待一切结束,我认为那是 .then()
工作。
您说这是 .then() 作业是对的。当你说
var countPhotos = Facebook.countTaggedPhotos()
您将 countPhotos 设置为等于 countTaggedPhotos().then() returns。在这种情况下,它不会 return 照片的数量。您可以访问照片数量的唯一位置是在 .then 中。
为了进一步帮助您,您需要提供您的代码
return http(options).then(function(data){...
因为在那里,你引用了照片,但我不知道它实际上是如何提供给你控制器中的 .then() 的。
因为这个问题我的头撞到墙上几个小时后,我找到了问题的根源和解决方案。
问题根源:递归
myself(id, target, accessToken, decodeURIComponent(res.paging.next));
一旦递归开始,我没有得到任何等待它们的承诺,导致我的问题,当第一个承诺结束时,他执行了 .then()
回调 returning 0 photos in the array并在结束其他页面的处理之前将控制器释放到 return。另一个错误是我在整个 countTaggedPhotos
方法中进行递归,仅更改为 http 回调。
解决方案:嵌套承诺
var promiseHttp = http(options).then(function myself(data){
var res = JSON.parse(data);
if(!res || res.error) {
console.log(!res ? 'error occurred while loading photos' : res.error);
return;
}
for (var photoIndex in res.data) {
var photo = res.data[photoIndex];
if (photo.tags) {
for(var tagIndex in photo.tags.data){
var tag = photo.tags.data[tagIndex];
if (tag.id == target) {
photos.push(photo);
}
}
}
}
if (res.paging && res.paging.next) {
var opt={ uri: decodeURIComponent(res.paging.next), method: 'GET' };
return http(opt).then(myself);
}
});
return promiseHttp.return(photos);
现在我的控制器能够等待每一页完成它的处理并且 return 照片正确。
我不知道这个解决方案是否最好,但它确实有效。如果有人要补充一些东西,一些最佳实践或其他东西,请随时发表评论。
我不太习惯 nodejs/javascript 中的 Promises,基本上我希望我的控制器 return 只有在我的 promise 完成后才给一个值 运行。
我的 Sails 应用程序中有以下服务。我正在使用请求承诺模块向 facebook 图 api.
发出 HTTP 请求 return http(options).then(function(data){
var res = JSON.parse(data);
if(!res || res.error) {
console.log(!res ? 'error occurred while loading photos' : res.error);
return;
}
for (var photoIndex in res.data) {
var photo = res.data[photoIndex];
if (photo.tags) {
for(var tagIndex in photo.tags.data){
var tag = photo.tags.data[tagIndex];
console.log('TAG_ID: '+tag.id + ' -> TARGET_ID: ' + target);
if (tag.id == target) {
photos.push(photo);
}
}
}
}
if (res.paging && res.paging.next) {
console.log('recursion in action!!');
myself(id, target, accessToken, decodeURIComponent(res.paging.next));
}
我的控制器是:
var countPhotos = Facebook.countTaggedPhotos(requesterId, targetId, accessToken).then(function(photos){
return res.json({photos: photos.length});
});
但是控制器在我的服务承诺结束之前 returning 0,当我查看日志时我可以看到它仍在执行循环。
如何让我的控制器在 return 之前等待一切结束,我认为那是 .then()
工作。
您说这是 .then() 作业是对的。当你说
var countPhotos = Facebook.countTaggedPhotos()
您将 countPhotos 设置为等于 countTaggedPhotos().then() returns。在这种情况下,它不会 return 照片的数量。您可以访问照片数量的唯一位置是在 .then 中。
为了进一步帮助您,您需要提供您的代码
return http(options).then(function(data){...
因为在那里,你引用了照片,但我不知道它实际上是如何提供给你控制器中的 .then() 的。
因为这个问题我的头撞到墙上几个小时后,我找到了问题的根源和解决方案。
问题根源:递归
myself(id, target, accessToken, decodeURIComponent(res.paging.next));
一旦递归开始,我没有得到任何等待它们的承诺,导致我的问题,当第一个承诺结束时,他执行了 .then()
回调 returning 0 photos in the array并在结束其他页面的处理之前将控制器释放到 return。另一个错误是我在整个 countTaggedPhotos
方法中进行递归,仅更改为 http 回调。
解决方案:嵌套承诺
var promiseHttp = http(options).then(function myself(data){
var res = JSON.parse(data);
if(!res || res.error) {
console.log(!res ? 'error occurred while loading photos' : res.error);
return;
}
for (var photoIndex in res.data) {
var photo = res.data[photoIndex];
if (photo.tags) {
for(var tagIndex in photo.tags.data){
var tag = photo.tags.data[tagIndex];
if (tag.id == target) {
photos.push(photo);
}
}
}
}
if (res.paging && res.paging.next) {
var opt={ uri: decodeURIComponent(res.paging.next), method: 'GET' };
return http(opt).then(myself);
}
});
return promiseHttp.return(photos);
现在我的控制器能够等待每一页完成它的处理并且 return 照片正确。
我不知道这个解决方案是否最好,但它确实有效。如果有人要补充一些东西,一些最佳实践或其他东西,请随时发表评论。