AngularJS:为啥即使显示正确,我也会得到 NaN?

Posted

技术标签:

【中文标题】AngularJS:为啥即使显示正确,我也会得到 NaN?【英文标题】:AngularJS: Why am I getting NaN for this even though they display correctly?AngularJS:为什么即使显示正确,我也会得到 NaN? 【发布时间】:2016-01-24 08:14:14 【问题描述】:

已编辑:下面代码中的 //Fix ... 和 //Error cmets 显示了答案

这对于 javascript 专家来说可能是愚蠢而明显的事情......但如果我能看到这是怎么回事,我会很危险。

这是我的 t.js

var angularApp = angular.module('myApp', []);

angularApp.controller('mainController', ['$scope', '$http', '$log',
                                function ($scope,   $http,   $log) 
    $scope.version = angular.version;
    var ctime = new Date();
    $scope.ctime = ctime.getTime() / 1000;
    $http.get('http://127.0.0.1:8765/').then(
      function(res)
        $scope.stime = res['data']['server-time'] / 1000;
        // Fix goes here: $scope.skew = $scope.stime - $scope.ctime;
        ,
      function(error)
        $log.warn('Unable to get time'););
    // Error here: this happens asynchronously to the $http.get!
    $scope.skew = parseFloat($scope.stime) - parseFloat($scope.ctime);
]);

... 和我的 html

<!DOCTYPE html>
<html lang="en-us" data-ng-app="myApp"><head><title>Time Skew</title>
    <meta charset="UTF-8">
    <link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" />
  </head><body>
        <header><nav class="navbar navbar-default">
            <div class="container">
                <div class="navbar-header">
                    <a class="navbar-brand" href="/">AngularJS</a></div>
                <ul class="nav navbar-nav navbar-right">
                    <li><a href="#"><i class="fa fa-home"></i>Home</a></li>
                </ul></div></nav></header>
        <div class="container">
            <div data-ng-controller="mainController">
                <div class="ng-cloak">Browser time: ctime</div>
                <div class="ng-cloak">Server &nbsp;&nbsp; time: stime</div>
                <div class="ng-cloak">Time skew: skew</div></div></div>
       <script src="//code.angularjs.org/1.4.7/angular.min.js"></script>
       <script src="t.js"></script>
    </body></html>

...下面是大致显示的内容:

Browser time: 1445735550.067
Server  time: 1445735550.085
Time skew: NaN

运行此程序时,Chrome 浏览器的开发人员工具 JavaScript 控制台上没有显示任何内容。 (在本次学习期间,我在那里看到了很多其他类型的错误……所以我知道它确实显示了我的语法错误、依赖注入失败等等——当这些存在时)。

我已经尝试过使用和不使用 parseFloat()。 (此外,对 class="ng-cloak" 的调用也无关紧要……尽管它们也没有按预期工作,但将它们取出没有效果)。我从我的 * / 1000* (除法)表达式中获得所需的浮点表示这一事实表明它们在代码中的这两个点被视为数字。我尝试删除除法并使用 parseInt() 而不是 parseFloat()

(虽然我认为这与这个问题无关,但这里是提供此时间服务的 node.js“应用程序”:

// tserver.js:
var http = require("http");
http.createServer(function (req, response) 
    var headers = 
        'Content-Type:': 'application/json',
        // Extra headers suggested by http://***.com/a/29548846/149076
        // ... to resolve: "Control-Allow-Origin' header is present on the requested resource"
        // error from Angular.js $http.get() ...
        'Access-Control-Allow-Headers': 'Content-Type',
        'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
        'Access-Control-Allow-Origin': '*'
        ;
    response.writeHead(200, headers);
    var d = new Date();
    response.end(JSON.stringify( 'server-time': d.getTime() ));
).listen("8765");

...虽然很明显我从我的“服务”中得到了一个有效的整数(或应该解析为整数的字符串)。 (HTML中显示的值与“ctime”在几毫秒内的值一致)。

当我发布这个问题时,我发现了一些关于 JavaScript NaN 结果的其他问题......这些似乎都不适用于这里。我什至尝试添加一个 $scope.tst = parseFloat('12345.97') - parseFloat('12345.67'); 并将其添加到我的 HTML 并得到一个完全可预测的数字结果......实际上我使用这些全长数字,如此处所示,以确保数字大小不是什么奇怪的问题。我还尝试在 $scope.Xtime 变量上调用“.toString()”。

那么我在这里做错了什么?

【问题讨论】:

【参考方案1】:

$http 是异步的,您尝试在请求完成之前不存在的变量上使用 parseFloat

将您的计算放入 promise 回调中

$http.get('http://127.0.0.1:8765/').then(function (res) 
    $scope.stime = res['data']['server-time'] / 1000;
    // can do calc here
    $scope.skew = parseFloat($scope.stime) - parseFloat($scope.ctime);
,function (error) 
    $log.warn('Unable to get time');
);

【讨论】:

好答案,领先我几秒钟。 噢!受事件模型影响。 Must.Remember.JavaScript.is.Implicitly.Multi-threaded! @JimDennis 不,它实际上是单线程的,但有些操作是异步的 好的。 Must.Remember.JavaScript.is.Executed.in.Implicitly.Asynchronous.Event.Loop! 在这种情况下,对 parseFloat() 的调用是多余的(如我的编辑所示)。我想应该使用某种绑定或监视 ... 或设置我的回调函数来替换 DOM 中的文本,而不是使用 ... 模板引用或其他东西。此修复有效,但我仍然得到 ng-cloak 应该修复的闪烁。 :(

以上是关于AngularJS:为啥即使显示正确,我也会得到 NaN?的主要内容,如果未能解决你的问题,请参考以下文章

为啥即使数据库中不存在 id 和/或用户名我也会成功

为啥即使存在列,我也会有 ORA-00904?

为啥即使我有一个 catch() 函数,我也会收到 UnhandledPromiseRejectionWarning?

为啥即使实现了 Iterable,我也会收到 foreach 编译器错误?

为啥即使我使用 sparse_categorical_crossentrpy,我也会收到“收到超出 [0, 1) 有效范围的标签值 6”?

为啥即使在包含 math.h 并使用 -lm 链接到数学库之后我也会收到“未定义的符号:.sqrtf”