如何将同步ajax转换为异步?

时间:2014-06-23 17:09:47

标签: javascript jquery ajax asynchronous coffeescript

我想要完成的事情

我正在尝试检查服务器时间并将其与预设的关闭时间进行比较,以防止用户点击过期的促销商品(并显示该商品已过期)但是我正在尝试如何实现这一目标。 ; s与同步调用混合

我知道async:false是一个非常糟糕的主意,它在Firefox中无法工作(适用于Chrome和IE),但它完全符合我的要求。我很难搞清楚如何将我的代码转换为异步。如果我将部分代码异步更改,那么依赖于它的所有其他代码部分都会因为时间关闭而崩溃。

以前的代码 - 如果sale_closed()

,我会打电话给所有人
@get_server_time: (url) ->
$.ajax(
  url: url + '/servertime'
  type: 'GET'
  async: false
)

@sale_closed: () ->
   if not @is_valid_user
     return true
   if Config.override_bid_closed?
     return false
   if @get_server_time(url) > sale_end
     return true
   return false

我试图做但是没有工作

的CoffeeScript

@get_server_time: (url) ->
$.ajax(
  url: url + '/servertime'
  type: 'GET'
)

@sale_closed: () ->
  @get_server_time(url).done (data) ->
   if not @is_valid_user
     return true
   if Config.override_bid_closed?
    return false
   if data > sale_end
     return true
   return false

中的相同代码

的Javascript:

function get_server_time (url) {
  return $.ajax({
    url: url + '/servertime',
    type: 'GET'
  });
};

function sale_closed() {
    get_server_time(url).done(function(data) {
     if (!this.is_valid_user()) {
      return true;
    }
    if (Config.override_sale_closed != null) {
      return false;
    }
    if (data > sale_end) {
      return true;
    }
    return false;
  });
};

这是对的吗?

期望从

更改我的所有sale_close代码
foo: () ->
  if sale_closed()
    /* do something */

do_something: () ->
 /* do something */

foo: () - >
  sale_closed(do_something)

这是一个巨大的噩梦,因为我必须改变很多代码,并且会使它们全部异步,这可能会破坏所有其他功能,这些功能可以打破“foo”,“foo2”和“foo2”等。等等(之前是同步的)。

有什么保证变量do_something读取将在上下文中并且在执行时具有相同的值吗?

感谢您的帮助,因为我试图绕过这个


2 个答案:

答案 0 :(得分:0)

尝试进行一些日志记录,如果问题是您无法访问该功能@is_valid_user,请尝试更改此

  @get_server_time(url).done (data) ->

到这个

  @get_server_time(url).done (data) =>

fat arrow将完成的回调函数绑定到this的当前上下文,从而保留调用this.is_valid_user的能力。如果没有更大的代码上下文,很难确切知道这是否适合你,但我可能会先尝试一下。

答案 1 :(得分:0)

  

这是对的吗?

不是真的。您不能像在同步代码中那样return来自异步回调。相反,你会想要使用Promises:

@get_server_time: (url) ->
  $.ajax(
    url: url + '/servertime'
    type: 'GET'
  )

@sale_closed: () ->
  if not @is_valid_user
    return $.when true
  if Config.override_bid_closed?
    return $.when false
  @get_server_time(url).then (data) ->
    data > sale_end
  

是否期望更改所有调用sale_close的代码?

是的,您需要将所有内容更改为回调样式。有了承诺,变化不会很大,而且流量保持线性。

  

有什么保证变量do_something读取将在上下文中并且在执行时具有相同的值吗?

您应该在do_something函数内部声明foo(或者只使用函数表达式),这将保证您需要的所有变量都在范围内。如果您需要正确的this上下文,请使用胖箭头函数。