【问题标题】:Best way to return values from async functions in javascript从javascript中的异步函数返回值的最佳方法
【发布时间】:2017-05-22 03:20:06
【问题描述】:

我正在使用具有异步调用的 nodejs 的 twit 库,并且我制作了这样的函数:

function getUserFromSearch(phrase) {
    T.get('search/tweets', { q: phrase+' lang:pt', count: 1 }, function(err, data, response) {
    data['statuses'].forEach(function(element) {
        var result = "maybe";
        say('getting user profile from search for '+phrase, result);
        console.log(element);
        return element['user']['screen_name'];
    }, this);
    })
}

因为 T.get() 是异步执行的,所以无论何时执行

var username = getUserFromSearch('banana');

我收到username=undefined,因为退货需要时间。显而易见的解决方案是实现这样的回调:

function getUserFromSearch(phrase, callback) {
    T.get('search/tweets', { q: phrase+' lang:pt', count: 1 }, function(err, data, response) {
    data['statuses'].forEach(function(element) {
        var result = "maybe";
        say('getting user profile from search for '+phrase, result);
        console.log(element);
        callback(element['user']['screen_name']);
    }, this);
    })
}

但我不认为这是最好的解决方案,因为我需要为此创建一个回调函数。有没有办法像这样传递用户名“指针”:getUserFromSearch('banana', username);,以使函数改变用户名的值?还有更好的方法吗?

【问题讨论】:

    标签: javascript node.js asynchronous callback


    【解决方案1】:

    有没有办法传递用户名'指针'

    不,没有。 JavaScript 没有对变量的引用。

    您可以传入带有username 的对象属性 并让它设置该属性,但这会将getUserFromSearch 紧密耦合到特定对象并且不可组合。

    Promise 是处理这种情况的好方法。它们是可组合的,并围绕成功和失败提供清晰的语义:

    function getUserFromSearch(phrase) {
        return new Promise(function(resolve, reject) {
            T.get('search/tweets', { q: phrase + ' lang:pt', count: 1 }, function(err, data, response) {
                if (err) {
                    reject(err);
                } else {
                    data['statuses'].forEach(function(element) {
                        var result = "maybe";
                        say('getting user profile from search for ' + phrase, result);
                        resolve(element['user']['screen_name']);
                    }, this);
                }
            })
        });
    }
    

    用法:

    getUserFromSearch(phrase).then(function(result) {
        username = result;
    });
    

    是的,还有一个回调,但它是一个很容易与其他人组合的回调。


    使用 ES2015 语法:

    function getUserFromSearch(phrase) {
        return new Promise((resolve, reject) => {
            T.get('search/tweets', { q: phrase + ' lang:pt', count: 1 }, function(err, data, response) {
                if (err) {
                    reject(err);
                } else {
                    data['statuses'].forEach(element => {
                        const result = "maybe";
                        say('getting user profile from search for ' + phrase, result);
                        resolve(element['user']['screen_name']);
                    });
                }
            })
        });
    }
    

    用法:

    getUserFromSearch(phrase).then(result => {
        username = result;
    });
    

    【讨论】:

    • 可以在nodejs中使用ES2015语法吗?
    • @Gatonito:是的。 Node v6.x 具有除模块之外的完全支持(以及尾调用优化,除非您使用标志)。 v5.x 和 v4.x 部分支持。
    • 那么你可以这样使用它:var username = await getUserFromSearch(phrase); 一旦节点支持async/await
    【解决方案2】:

    由于 JavaScript 没有指针的概念,您可以在调用函数之前创建一个对象,并将该对象作为第二个参数传递给函数。将函数的结果赋值给对象的属性。

    您的代码如下所示:

    function getUserFromSearch(phrase,obj) {
    T.get('search/tweets', { q: phrase+' lang:pt', count: 1 }, function(err, data, response) {
    data['statuses'].forEach(function(element) {
        var result = "maybe";
        say('getting user profile from search for '+phrase, result);
        console.log(element);
        obj.username = element['user']['screen_name'];
    }, this);
    })
    }
    
    var obj = {username:null}
    getUserFromSearch('banana',obj);
    

    【讨论】:

      【解决方案3】:

      这就是 javascript 的工作方式。
      由于这是一个异步函数,所以你需要按照你说的去做。

      getUserFromSearch('banana', function(username){
         //do something with username here
      });
      

      你可以做的是使用async.js 之类的东西来减少嵌套回调地狱......

      【讨论】:

      • 你觉得这个想法怎么样:stackoverflow.com/questions/5292159/…
      • 我可以传递一个包含“用户名”属性的对象并让函数对其进行修改,而不是传递回调。
      • 如果人们发表评论会很高兴,而不仅仅是飞越投票
      猜你喜欢
      • 1970-01-01
      • 2011-09-06
      • 2020-12-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-26
      • 2022-01-14
      相关资源
      最近更新 更多