我已阅读以下问题和相应的深刻见解,并了解异步回调函数的工作原理 -
How do I return the response from an asynchronous call?
How to return value from an asynchronous callback function?
Returning value from asynchronous JavaScript method?
但仍然无法成功返回相应的vaule。以下是代码 -
function foo(callback){
request('some-url.json', function (error, response, body) {
//Check for error
if(error){
//error body
}
//Check for right status code
if(response.statusCode !== 200){
//response body
}
//All is good. Print the data
var data = JSON.parse(body);
callback(data.some-property);
});
}
module.exports = {
foo:foo(function(result){
console.log(result); //works
return result; //doesn't work
}),
};
我能够在控制台日志中获得预期结果,但仍然无法返回该值。
错误:TypeError: Property 'foo' of object #<Object> is not a function
问题:
1.回调函数执行是否正确?
2.我该怎么做才能成功返回值?
编辑:最后在与Paarth进行了广泛的对话后,我决定使用promise.js,这将允许我间接返回我从函数中寻找的值。有关promise.js的更多资源 -
https://gist.github.com/domenic/3889970
http://colintoh.com/blog/staying-sane-with-asynchronous-programming-promises-and-generators
答案 0 :(得分:1)
没有真正的方法可以从异步代码返回转到同步代码。您可以通过使用将延迟操作视为数据的promises来接近,这样您就可以返回promise对象并设置稍后将发生的操作,但是使用回调,您必须继续创建回调。
您可以在https://www.promisejs.org/找到一些有关承诺的基本信息(虽然我不认可promise.js)和更多here。
如果您在ES5中工作,Bluebird和Q是众所周知的承诺库。 Promise是ES6中的本机功能。
因此,忽略模块语法,请假设您尝试使用该功能。
function something() {
...
// result not bound, foo is not called
foo(function(result){
console.log(result); //result was passed into this callback and is bound
return result; //result is still bound but returning does nothing. No one is waiting for the return value.
});
// code below this point probably already executed before your console.log in the foo callback. No one is waiting for the return.
}
直接回答您的问题:
是的,在您尝试返回某些内容之前,您已正确调用了foo。返回并不是一个适用于回调函数的概念。您只能将数据传递给其他回调。
您永远不会返回该值。
让我们说我有foo,它接受回调。如果我想对foo的另一个函数foo2采取行动,我必须调用
function foo2 () {
foo(function(result) {
//act on result
}
}
现在让我们说我希望foo2将foo1的结果返回给另一个函数。好吧,有了回调,我无法做到。我只能让foo2接受另一个回调并传递数据。
function foo2 (callback) {
foo(function(result) {
callback(result);
}
}
答案 1 :(得分:1)
那是因为module.exports不会等待请求(异步)完成。只需导出该功能并在需要时调用它。
您可以导出该功能:
//yourController.js
module.exports = foo;
现在需要在其他文件中的某处使用该函数并调用它:
// another.js
var foo = require('yourController.js');
foo(function(result){
// your result is here
});
或
require('yourController.js')(function(result){/* Do whatever with result */});