【问题标题】:How to use correctly Deferrers?如何正确使用延迟器?
【发布时间】:2014-08-14 01:57:40
【问题描述】:
var numerodepuntos;
$.when($.get('/u2', function(ospuntosyou) {
    numerodepuntos = parseFloat($(ospuntosyou).find('#field_id-13 dd').text());
    console.log('Esto: '+numerodepuntos)
})).done(console.log('Esto: '+numerodepuntos));

我正在尝试使用此代码并从 ajax 请求中获取一个变量,但第二个 console.log 返回未定义,就像它是立即加载的,而不是在 $get 完成后加载。

【问题讨论】:

  • 你为什么要两次console.log('Esto: '+numerodepuntos)

标签: jquery ajax promise


【解决方案1】:

'done' 需要一个与 $.get 中的成功函数非常相似的函数。我也建议 你把它分成几部分来减少你的代码缩进。这是你的模式:

var numerodepuntos;
var promise = $.get('/u2', function(ospuntosyou) {
    numerodepuntos = parseFloat($(ospuntosyou).find('#field_id-13 dd').text());
    console.log('Esto: '+numerodepuntos)
})
promise.done(function(ospuntosyou) {
   numerodepuntos = parseFloat($(ospuntosyou).find('#field_id-13 dd').text());
   console.log('Esto: '+numerodepuntos));
}

当然因为done函数和success函数是一样的,所以你只需要这个:

var promise = $.get('/u2')
promise.done(function(ospuntosyou) {
   var numerodepuntos = parseFloat($(ospuntosyou).find('#field_id-13 dd').text());
   console.log('Esto: '+numerodepuntos));
}

【讨论】:

  • 没有理由在一个承诺上使用$.when()。只需在 Promise 上使用 .done()
【解决方案2】:

问题在于 JavaScript 不是 Scala - 没有名称传递。所以.done(console.log(...)) 中的console.log$.when 执行后立即执行,并且该调用的result 被传递给done(例如undefined)。

将您的最终done 调用包装在一个函数中,一切都会奏效:

$.when($.get('/u2', function(ospuntosyou) {
    var numerodepuntos = parseFloat($(ospuntosyou).find('#field_id-13 dd').text());
    console.log('Esto: '+numerodepuntos);
    return numerodepuntos;
})).done(function doneCallback(numerodepuntos) {
    console.log('Esto: '+numerodepuntos);
});

值得注意的是,所有这些也可以大大简化:

$.get('/u2', function getCallback(ospuntosyou) {
  var numerodepuntos = parseFloat($(ospuntosyou).find('#field_id-13 dd').text());
  console.log('Esto: '+numerodepuntos);
  return numerodepuntos;
}).done(function doneCallback(numerodepuntos) {
    console.log('Esto: '+numerodepuntos);
});

【讨论】:

    【解决方案3】:

    我建议您只使用 Promise 或只使用成功处理程序,而不是两者混合使用,这样您就不会造成这种混乱。例如,我不确定 jQuery 中是否有关于是否首先执行回调或承诺的内部规范。无论哪种情况,您都不应该依赖它们之间的时间安排。

    这是一种只使用不会出现问题的 Promise 的方法。

    $.get('/u2').done(function(ospuntosyou) {
        var numerodepuntos = parseFloat($(ospuntosyou).find('#field_id-13 dd').text());
        console.log('Esto: '+numerodepuntos)
    });
    

    注意 - 我在 .done() 处理程序中声明了 numerodepuntos,这很重要,因为从 .done() 处理程序外部填充该变量的时间不确定,您应该只在.done() 处理程序或在您调用并从那里传递数据的函数中。如果您对此感到困惑,请阅读有关从 ajax 调用返回的数据的参考:

    How do I return the response from an asynchronous call?

    仅供参考,没有理由在一个承诺上使用$.when()。您可以直接使用$.get() 返回的promise 上的方法,这样可以避免要求$.when() 创建另一个promise。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-02-21
      • 2021-06-17
      • 2018-06-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-11
      • 1970-01-01
      相关资源
      最近更新 更多