静态响应工作!而异步不起作用

Static response WORKS! While Asynchronous doesn't work

本文关键字:异步 不起作用 响应 工作 静态      更新时间:2023-09-26

我正在创建一个用于实时图表显示的角指令,这里是返回所有内容的代码,包括link:function() { }内部指令。

下面是静态指令的代码,它工作得很好
angular.module('app').directive("flotChartRealtime", [
    function() {
        return {
            restrict: "AE",
            link: function(scope, ele) {
                var realTimedata,
                    realTimedata2,
                    totalPoints,
                    getSeriesObj,
                    getRandomData,
                    getRandomData2,
                    updateInterval,
                    plot,
                    update;
                return realTimedata = [],
                    realTimedata2 = [],
                    totalPoints = 100,
                    getSeriesObj = function() {
                        return [
                            {
                                data: getRandomData(),
                                lines: {
                                    show: true,
                                    lineWidth: 1,
                                    fill: true,
                                    fillColor: {
                                        colors: [
                                            {
                                                opacity: 0
                                            }, {
                                                opacity: 1
                                            }
                                        ]
                                    },
                                    steps: false
                                },
                                shadowSize: 0
                            }, {
                                data: getRandomData2(),
                                lines: {
                                    lineWidth: 0,
                                    fill: true,
                                    fillColor: {
                                        colors: [
                                            {
                                                opacity: .5
                                            }, {
                                                opacity: 1
                                            }
                                        ]
                                    },
                                    steps: false
                                },
                                shadowSize: 0
                            }
                        ];
                    },
                    getRandomData = function() {
                        if (realTimedata.length > 0)
                            realTimedata = realTimedata.slice(1);
                        // Do a random walk
                        //console.log(realTimedata);
                        while (realTimedata.length < totalPoints) {
                            var prev = realTimedata.length > 0 ? realTimedata[realTimedata.length - 1] : 50,
                                y = prev + Math.random() * 10 - 5;
                            if (y < 0) {
                                y = 0;
                            } else if (y > 100) {
                                y = 100;
                            }
                            realTimedata.push(y);
                        }
                        // Zip the generated y values with the x values
                        var res = [];
                        for (var i = 0; i < realTimedata.length; ++i) {
                            res.push([i, realTimedata[i]]);
                        }
                        return res;
                    },
                    getRandomData2 = function() {
                        if (realTimedata2.length > 0)
                            realTimedata2 = realTimedata2.slice(1);
                        // Do a random walk
                        while (realTimedata2.length < totalPoints) {
                            var prev = realTimedata2.length > 0 ? realTimedata[realTimedata2.length] : 50,
                                y = prev - 25;
                            if (y < 0) {
                                y = 0;
                            } else if (y > 100) {
                                y = 100;
                            }
                            realTimedata2.push(y);
                        }

                        var res = [];
                        for (var i = 0; i < realTimedata2.length; ++i) {
                            res.push([i, realTimedata2[i]]);
                        }
                        return res;
                    },
                    // Set up the control widget
                    updateInterval = 500,
                    plot = $.plot(ele[0], getSeriesObj(), {
                        yaxis: {
                            color: '#f3f3f3',
                            min: 0,
                            max: 100,
                            tickFormatter: function(val, axis) {
                                return "";
                            }
                        },
                        xaxis: {
                            color: '#f3f3f3',
                            min: 0,
                            max: 100,
                            tickFormatter: function(val, axis) {
                                return "";
                            }
                        },
                        grid: {
                            hoverable: true,
                            clickable: false,
                            borderWidth: 0,
                            aboveData: false
                        },
                        colors: ['#eee', scope.settings.color.themeprimary],
                    }),
                    update = function() {
                        plot.setData(getSeriesObj()); // getting .data filled here perfectly
                        plot.draw();
                        setTimeout(update, updateInterval);
                    },
                    update();
            }
        };
    }
]);

我的代码与HTTP请求不工作

 getSeriesObj = function () {
     return [{
         data: getRandomData(function(res) {
             console.log(res) // getting array result here from http call but not returning to data:
             return res; 
         }),
         lines: {
             show: true,
             lineWidth: 1,
             fill: true,
             fillColor: {
                 colors: [{
                     opacity: 0
                 }, {
                     opacity: 1
                 }]
             },
             steps: false
         },
         shadowSize: 0
     }, {
         data: getRandomData2(function (res) {
             return res;
         }),
         lines: {
             lineWidth: 0,
             fill: true,
             fillColor: {
                 colors: [{
                     opacity: .5
                 }, {
                     opacity: 1
                 }]
             },
             steps: false
         },
         shadowSize: 0
     }];
 },
 getRandomData = function (callback) {
     var authToken = window.localStorage.getItem('token');
     var url = $rootScope.apiPath + 'Elasticsearch/countget?token=' + authToken;
     var res = [];
     $http.get(url).then(function (result) {
         realTimedata = result.data;
         if (realTimedata.length > 0)
         //result = [10,22,33,11,32,88,77,66,21,90,92,98,99.9,88.8,76,66,56,88];
         for (var i = 0; i < realTimedata.length; ++i) {
             var y = realTimedata[i] + Math.random() * 10 - 5;
             if (y < 0) {
                 y = 0;
             } else if (y > 100) {
                 y = 100;
             }
             res.push([i, y]);
         }
         callback(res);
     });
 },

:

当我尝试以下代码:

update = function () {
    //console.log(getSeriesObj());
    plot.setData(getSeriesObj()); // .data property gets undefined
    plot.draw();
    setTimeout(update, updateInterval);
}

函数getSeriesObj()返回返回data属性到undefined的对象数组,原因是什么?

如何解决这个问题?

注意:这与这个问题有很大的不同。

什么时候做

data: getRandomData(function(res) {
    return res; 
});

getRandomData的rValue赋值给data

如你的帖子所述,getRandomData现在没有return语句,所以返回undefined

这里的主要问题是您期望plot.setData(getSeriesObj());工作synchronously

步骤
  1. 获取数据填充plot
  2. 设置数据为plot
  3. 再次更新

现在,由于http请求异步工作,您不能期望从getSeriesObj()检索值。你必须认为getSeriesObj现在异步工作,所以你只能使用回调,当资源准备好使用时将被触发

所以更新方法变成

update = function () {
    var updateTime = +new Date;
    getSeriesObj(function(res){ // execute that stuff when ready
        plot.setData(res);
        plot.draw();
        setTimeout(update, Math.max(10, updateInterval - (+new Date - updateTime)) );
    });
}

getSeriesObj

getSeriesObj = function (callback) {
    getRandomData(function(res) {
        getRandomData2(function(res2){
            var data = [{
                data: res,
                lines: {
                    show: true,
                    lineWidth: 1,
                    fill: true,
                    fillColor: {
                        colors: [{
                            opacity: 0
                        }, {
                            opacity: 1
                        }]
                    },
                    steps: false
                },
                shadowSize: 0
            }, {
                data: res2,
                lines: {
                    lineWidth: 0,
                    fill: true,
                    fillColor: {
                        colors: [{
                            opacity: .5
                        }, {
                            opacity: 1
                        }]
                    },
                    steps: false
                },
                shadowSize: 0
            }];
            callback(data); // now the ressource obj is now ready to be used
        });
    });
}