苦苦于从JavaScript回调函数返回一个对象

时间:2014-01-28 03:19:36

标签: javascript

我正在使用AddThis JavaScript API。我正在努力解决的方法在这里记录:

http://support.addthis.com/customer/portal/articles/1137944-getting-counter-values-dynamically

我可以从“obj”对象获取我需要的数据 - 但只能在该方法中获取。我似乎无法将数据返回到我可以在我的jQuery循环中使用的全局变量。问题是我对Javascript对象的理解有限。这是我的代码:

    addthis.addEventListener('addthis.ready', addthisReady);
function addthisReady() {

    var myobj = {};
    addthis.sharecounters.getShareCounts({service: ['facebook', 'twitter', 'pinterest'], countUrl: 'http://www.addthis.com/'}, function(obj) {
        console.log(obj); // OK
        myobj = obj;

    });
    console.log(myobj); // Not OK
}

我的最终目标是在页面上放置多个文章链接,然后使用jQuery和此API方法将总共享计数附加到其链接标题。例如;

  • Article Link X(22股)
  • Article Y(13股)
  • Article Link Z(13股)

任何帮助都会很棒。

CJ

进展更新 - 差不多......

下面的代码会考虑您的建议以及API供应商提供的示例。它几乎就在那里,但回调只是随机更新每个循环中的一个元素。

示例代码 - 已注释掉 - 表示应该可以多次调用该方法。

以下是代码:

$(document).ready(function(){


addthis.addEventListener('addthis.ready', addthisReady);
function addthisReady() {
    /*
    addthis.sharecounters.getShareCounts('facebook', function(obj) {
        document.getElementById('basic-example').innerHTML = '<code>'+JSON.stringify(obj, undefined, 4)+'</code>';
    });

    addthis.sharecounters.getShareCounts(['facebook', 'twitter', 'pinterest'], function(obj) {
        document.getElementById('multiple-services').innerHTML = '<code>'+JSON.stringify(obj, undefined, 4)+'</code>';
    });

    addthis.sharecounters.getShareCounts({service: 'facebook', countUrl: 'http://www.addthis.com/'}, function(obj) {
        document.getElementById('specific-url').innerHTML = '<code>'+JSON.stringify(obj, undefined, 4)+'</code>';
    });

    addthis.sharecounters.getShareCounts({service: ['facebook','twitter'], countUrl: 'http://www.addthis.com/'}, function(obj) {
        document.getElementById('specific-url-multiple-services').innerHTML = '<code>'+JSON.stringify(obj, undefined, 4)+'</code>';
    });
    */

    $('.ico-shares').each(function(index) {

        var elem = this;
        var share_url  =  $(elem).attr('href').split('#')[0];
        var shareLabel = $(elem).text();
        var total_count = 0;

        //Request Counts
        addthis.sharecounters.getShareCounts({service: ['facebook', 'twitter'], countUrl: share_url}, function(obj) {

            for (var key in obj)
            {
                total_count  += obj[key].count;
            }
            if (total_count > 0)
            {
                shareLabel = total_count + ' Share';
            }
            if (total_count > 1)
            {
                shareLabel = total_count + ' Shares';
            }
            alert(shareLabel);
            $(elem).text(shareLabel);

        });
    });
}

});

我的网址位于:http://banarra.cjweb.com.au/html/news_article.php

请注意底部有3个“更多新闻”文章,但只有一篇文章更新了分享链接。

非常感谢你的时间。

CJ

2 个答案:

答案 0 :(得分:3)

您发布的代码不会成为问题。

如果您发送您的请求,然后等待几秒钟,然后再使用控制台检查变量的值,你应该看到它设置为您所期望的价值。

问题是异步性。

看到的,当你发送一个请求关闭的服务器(即:当该功能实际上火灾),它不坐在那里,等待它回来,移动的代码的下一行之前

因此,如果您的代码如下:

var myObj = {};
getAsyncData(function myCallback (o) { myObj = o; });
console.log(myObj);

实际上会发生的是功能即将启动,您的代码将继续运行。

服务器尚未返回您的数据,因此myObj === {} 一段时间后,服务器将返回您的数据,并运行您提供的功能。

所以,如果你回来一段时间:

setTimeout(function () { console.log(myObj); }, 10000); // 10 sec

然后你应该看到它已被设置。

这里的诀窍是你实际上需要在你的异步代码中触发东西 你的程序的其余部分不知道任何改变或任何新的东西,它肯定没有坐下来等待它。

var myObj = {};
getAsyncData(function (o) { myObj = o; doStuff(myObj); });
var doStuff = function (obj) { console.log("Back from the server"); console.log(obj); };

为此,我建议查看评论中的链接。

编辑

要更好地把握问题(不是很多解决方案),想象你的异步调用使用setTimeout火的功能,并传递数据。
您不希望整个JS应用程序坐下来等待setTimeout中的一次更改。

var data_is_set = false,
    get_data = function (callback) {
        var data = true,
            time_to_wait = 3000; // 3sec
        setTimeout(function () { callback(data); }, time_to_wait);
    };

get_data(function (val) { data_is_set = val; });

console.log(data_is_set); // false

程序的其余部分将继续运行,直到该时间结束,然后调用您的函数 没有人知道发生了什么,所以你需要创建现在触发更新的函数,你可以在你的回调中调用。

答案 1 :(得分:1)

你能回复obj吗?

var myobj = addthis.sharecounters.getShareCounts({service: ['facebook', 'twitter', 'pinterest'], countUrl: 'http://www.addthis.com/'}, function(obj) {
    console.log(obj); // OK
    return obj;
});