【问题标题】:AJAX request not working unless alert() is used [duplicate]除非使用 alert(),否则 AJAX 请求不起作用[重复]
【发布时间】:2016-05-11 17:17:56
【问题描述】:

我正在发出 http- 请求以获取一些信息并在条形图中显示它们。除非我包含alert(" ")

,否则它不起作用

几乎一切正常,但没有alert(),图表将无法正常工作。我怎么解决这个问题?

app.controller('StatisticsCtrl', function ($scope, GitHubService) {


    // funktioniert - Test
    var getFollowedTmp = 0;
    var getFollowersTmp = 0;
    var getStarredTmp = 0;//Favoriten

    GitHubService.getFollowed(function (data) {
        getFollowedTmp = data.length;
    });
    GitHubService.getFollowers(function (data) {
        getFollowersTmp = data.length;
    });
    GitHubService.getStarred(function (data) {
        getStarredTmp = data.length;
    });


    alert("");
    var ctx = document.getElementById("profChart");
    var myChart = new Chart(ctx, {
        type: 'bar',
        data: {
            labels: ["Followers", "Following", "Starred"],
            datasets: [{
                label: 'Quantity',//Anzahl
                backgroundColor: "rgba(0,51,48,0.2)",
                borderColor: "rgba(0,51,48,0.2)",
                borderWidth: 1,             
                data: [getFollowersTmp, getFollowedTmp, getStarredTmp]
            }]
        },

        options: {
                scales: {
                    yAxes: [{
                        ticks: {
                            beginAtZero:true
                        }
                    }]
                }
            }
        });

});

【问题讨论】:

  • 在回调中做事

标签: javascript http httprequest chart.js


【解决方案1】:

GitHubService 中的方法是异步的。当您调用 alert("") 时,您将阻止执行转到下一行,从而为 git hub 服务提供运行和返回的时间。

这是一个使用 Jquery 进行 chaning 的示例。其他js框架,会有类似的概念。

var task1  = $.getJSON("http://resourceUri");
var task2  = $.getJSON("http://resourceUri2");

$.when(task1, task2).done(function(task1Response, task2Response){
   var task1Result = task1Response[0];
   var task2Result = task2Response[0];

   //Do something with the data. Charting?
});

【讨论】:

  • 那我需要做什么?
  • 按照 KMC 的回答,我会将您的服务调用包装在一个承诺中,然后在成功时将项目绑定到 UI
  • 那么根据 rlcrews 的评论,你能看到调用 GitHubService.getStarred() 时返回的内容吗?如果它是一个承诺对象(参考 jquery api),你可以做函数链接。例如)GitHubService.getStarred().done(function(){ //做某事})
  • 哦,GitHubService 是你自己的抽象还是 GitHub 的一部分?
  • 如果你不想花时间学习“承诺”和延迟对象的概念,可以看看底部的“riscarrott”解决方案。
【解决方案2】:

没有alert 就无法工作的原因是GitHubService 调用是异步的,因此在您呈现图表时数据不存在。

它与alert 一起工作的原因是因为alert 暂停了执行(公平地说,这有点神奇),所以当您关闭警报时,请求已经完成。

在渲染图表之前,您需要等待三个 GitHub 服务调用完成。

这可以这样实现:

function tryRender() {
    if (getFollowedTmp && getFollowersTmp && getStarredTmp) {
         var myChart = new Chart(...);
    }
}

GitHubService.getFollowed(function (data) {
    getFollowedTmp = data.length;
    tryRender();
});
GitHubService.getFollowers(function (data) {
    getFollowersTmp = data.length;
    tryRender();
});
GitHubService.getStarred(function (data) {
    getStarredTmp = data.length;
    tryRender();
});

但这并不过分优雅。如果您的 GitHubService 调用返回 promises(许多 ajax 库都这样做),您可以这样做:

Promise.all([
    GitHubService.getFollowed(),
    GitHubService.getFollowers(),
    GitHubService.getStarred()
]).then(function(result) {
    var getFollowedTmp = result[0].length;   
    var getFollowersTmp = result[1].length;
    var getStarredTmp = result[2].length;
    var myChart = new Chart(...);
});

【讨论】:

  • 我喜欢你的第一个解决方案。很好的解决方法,如果我们不使用承诺。
  • 我这样尝试它不起作用:
  • 第一个解决方案只有在每个 GitHubService 返回数据时才有效,如果它返回一个空数组,它仍然会失败。因此,最好将“getFollowedCompleted”、“getFollowersCompleted”或“getStarredCompleted”标志与数据分开。
【解决方案3】:

“删除阻塞调用会破坏我的代码”的常见原因之一是阻塞调用为浏览器提供了加载资源的时间。

在你的情况下,我相信getFollowersTmp, getFollowedTmp, getStarredTmp 没有及时初始化。

解决方法之一是使用AngularJS's $q 确保在继续之前加载所有依赖项。

【讨论】:

  • 哈,没有任何解释就被否决了。
  • 我是 javascript 新手,如何初始化功能?
  • @thenewOne1234567890 Chain the promises,并且只执行其余代码,直到对GitHubService 的所有 3 次调用都完成。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多