【问题标题】:jQuery.post() scope issue while trying to overwrite global variable [duplicate]尝试覆盖全局变量时的jQuery.post()范围问题[重复]
【发布时间】:2014-09-28 22:24:28
【问题描述】:

我在与范围相关的代码中遇到了一些困难。 这是我的代码:

<script type="text/javascript">
    var totalHoras = {};
    var dadosCategorias = {"teste": "1234"};
    var t; // timeout handler para exibição de feedback para o usuário

    $().ready(function() {
        // obtém dados das categorias
        var obterDadosCategorias = function() {
            $.post(
                "{{ baseRoute }}/cadastro/categoria/listar"
                , {
                    "ajax": "true"
                }
            ).done(function(data) {
                var obj = $.parseJSON(data);
                if (obj.result) {
                    console.log(dadosCategorias); // returns 'object{"teste": "1234"}'
                    dadosCategorias = obj.data;
                    console.log(dadosCategorias); // returns 'string(11) "it works!!!"'
                } else {
                    alert('Erro interno: não foi possível obter os dados das categorias');
                }
            });
        };

        obterDadosCategorias();
        console.log(dadosCategorias); // returns 'object{"teste": "1234"}'

问题是:为什么第三次调用 console.log 返回原始 var 值?是不是应该被覆盖?

控制台应该是

'object{"teste": "1234"}'
'string(11) "it works!!!"'
'string(11) "it works!!!"'

但它是

'object{"teste": "1234"}'
'string(11) "it works!!!"'
'object{"teste": "1234"}'

我尝试在 $.ajax() 函数中使用带有窗口的“上下文”选项,但也不起作用:(

【问题讨论】:

  • 为什么第三个 console.log 会等待你的 POST 完成?它在 obterDadosCategorias() 之后立即运行,它没有任何时间来触发 POST 请求、获取响应、解析正文并重新分配 obterDadosCategorias 的内容
  • 当我阅读这篇文章时,我希望它是 'object{etc}'、'object{etc}'、'string(11) it works')。这既不是它的样子,也不是海报所期望的
  • 您不了解“异步”的含义(AJAX 中的 A)。尝试将唯一标识符放入您的 console.log 调用中(例如,console.log(1, dadosCategorias))以查看它们被调用的顺序。
  • 你们是对的。我将尝试发出同步请求。 (以及用于识别 console.log 调用提示的坦克)

标签: javascript jquery scope


【解决方案1】:

感谢 cmets 伙计们! :D

我找到了答案。问题根本不在于范围。实际上,对 console.log() 的调用并没有按照脚本的顺序进行。调用顺序之前是 312,现在是 123 :D 我将 ajax 方法更改为 $.ajax() 而不是 $.post() 并将选项 'async' 设置为 false 以实现此目的,如下所示:

<script type="text/javascript">
    var totalHoras = {};
    var dadosCategorias = {"teste": "1234"};
    var t; // timeout handler para exibição de feedback para o usuário

    $().ready(function() {
        // obtém dados das categorias
        var obterDadosCategorias = function() {
            $.ajax(
                "{{ baseRoute }}/cadastro/categoria/listar"
                , {
                    "type": "POST"
                    , "async": false
                    , "data": {
                        "ajax": "true"
                    }
                }
            ).done(function(data) {
                var obj = $.parseJSON(data);
                if (obj.result) {
                    console.log(1, dadosCategorias);
                    dadosCategorias = obj.data;
                    console.log(2, dadosCategorias);
                } else {
                    alert('Erro interno: não foi possível obter os dados das categorias');
                }
            });
        };

        obterDadosCategorias();
        console.log(3, dadosCategorias);

【讨论】:

  • 设置 async: false 是一个非常糟糕的设计理念......因为它看起来会在 ajax 请求期间阻止浏览器
  • 是的,请不要那样做。将函数传递给obterDadosCategorias 并在done 处理程序中调用它。
  • 为什么不呢?获取从此函数返回的数据是强制性的。如果没有响应,应用程序甚至无法运行,所以我想我可以让它同步。
猜你喜欢
  • 2014-09-17
  • 1970-01-01
  • 2011-11-20
  • 2020-11-15
  • 2020-02-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多