繁体   English   中英

从JavaScript中的异步函数返回值的最佳方法

[英]Best way to return values from async functions in javascript

我正在将twit库用于具有异步调用的nodejs,并做了如下函数:

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

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

没有办法传递用户名“指针”

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

您可以传入一个带有username 属性的对象,并对其进行设置,但这getUserFromSearch与特定对象紧密耦合,并且是不可组合的。

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

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

由于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);

这就是javascript的工作方式。
由于这是一个异步函数,因此您需要按照说明进行操作。

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM