即使使用回调函数也无法返回值

时间:2016-05-10 06:22:54

标签: javascript asynchronous

我已阅读以下问题和相应的深刻见解,并了解异步回调函数的工作原理 -

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

https://www.promisejs.org/

http://colintoh.com/blog/staying-sane-with-asynchronous-programming-promises-and-generators

另外值得一提:Bluebird&amp; q

2 个答案:

答案 0 :(得分:1)

没有真正的方法可以从异步代码返回转到同步代码。您可以通过使用将延迟操作视为数据的promises来接近,这样您就可以返回promise对象并设置稍后将发生的操作,但是使用回调,您必须继续创建回调。

您可以在https://www.promisejs.org/找到一些有关承诺的基本信息(虽然我不认可promise.js)和更多here

如果您在ES5中工作,BluebirdQ是众所周知的承诺库。 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.
}

直接回答您的问题:

  1. 是的,在您尝试返回某些内容之前,您已正确调用了foo。返回并不是一个适用于回调函数的概念。您只能将数据传递给其他回调。

  2. 您永远不会返回该值。

  3. 让我们说我有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 */});