Javascript 如何将setTimeout()与CoffeeScript重新同步?轨道5

Javascript 如何将setTimeout()与CoffeeScript重新同步?轨道5,javascript,ruby-on-rails,ruby,ajax,coffeescript,Javascript,Ruby On Rails,Ruby,Ajax,Coffeescript,我为我的AJAX通知代码开发了一个咖啡脚本。代码本身可以正常工作。我遇到的问题是,我决定使用setTimeout()而不是setInterval(),以避免耗尽线程并造成严重拥塞。我很少使用coffeescript,我需要帮助弄清楚如何正确地循环setTimeout函数。setTimeout成功地使用getNewNotifications()方法接收数据后,如何调用递归方法调用 通知。咖啡 class Notifications constructor: -> @notific

我为我的AJAX通知代码开发了一个咖啡脚本。代码本身可以正常工作。我遇到的问题是,我决定使用setTimeout()而不是setInterval(),以避免耗尽线程并造成严重拥塞。我很少使用coffeescript,我需要帮助弄清楚如何正确地循环setTimeout函数。setTimeout成功地使用getNewNotifications()方法接收数据后,如何调用递归方法调用

通知。咖啡

class Notifications
  constructor: ->
    @notifications = $("[data-behavior='notifications']")

    if @notifications.length > 0
      @handleSuccess @notifications.data("notifications")
      $("[data-behavior='notifications-link']").on "click", @handleClick

    setTimeout (=>
      @getNewNotifications()
    ), 5000

  getNewNotifications: ->
    $.ajax(
      url: "/new_notification_check.json"
      dataType: "JSON"
      method: "GET"
      success: @handleSuccess
    )

  handleClick: (e) =>
    $.ajax(
      url: "/notifications/mark_as_read"
      dataType: "JSON"
      method: "POST"
      success: ->
        $("[data-behavior='unread-count']").text(0)
    )

  handleSuccess: (data) =>
    items = $.map data, (notification) ->
      notification.template

    unread_count = 0
    $.each data, (i, notification) ->
      if notification.unread
         unread_count += 1

    $("[data-behavior='unread-count']").text(unread_count)
    $("[data-behavior='notification-items']").html(items)

jQuery ->
  new Notifications
class Notifications
  constructor: ->
    @notifications = $("[data-behavior='notifications']")

    if @notifications.length > 0
      @handleSuccess @notifications.data("notifications")
      $("[data-behavior='notifications-link']").on "click", @handleClick

    setTimeout (=>
      @getNewNotifications()
    ), 5000

  getNewNotifications: ->
    $.ajax(
      url: "/new_notification_check.json"
      dataType: "JSON"
      method: "GET"
      success: @handleSuccess
    )

  handleClick: (e) =>
    $.ajax(
      url: "/notifications/mark_as_read"
      dataType: "JSON"
      method: "POST"
      success: ->
        $("[data-behavior='unread-count']").text(0)
    )

  handleSuccess: (data) =>
    items = $.map data, (notification) ->
      notification.template

    unread_count = 0
    $.each data, (i, notification) ->
      if notification.unread
         unread_count += 1

    $("[data-behavior='unread-count']").text(unread_count)
    $("[data-behavior='notification-items']").html(items)

    setTimeout (=>
      @getNewNotifications()
    ), 5000        

jQuery ->
  new Notifications

我相信您应该能够将
setTimeout
添加到
handleSuccess
中,这将创建您正在寻找的递归调用:

通知。咖啡

class Notifications
  constructor: ->
    @notifications = $("[data-behavior='notifications']")

    if @notifications.length > 0
      @handleSuccess @notifications.data("notifications")
      $("[data-behavior='notifications-link']").on "click", @handleClick

    setTimeout (=>
      @getNewNotifications()
    ), 5000

  getNewNotifications: ->
    $.ajax(
      url: "/new_notification_check.json"
      dataType: "JSON"
      method: "GET"
      success: @handleSuccess
    )

  handleClick: (e) =>
    $.ajax(
      url: "/notifications/mark_as_read"
      dataType: "JSON"
      method: "POST"
      success: ->
        $("[data-behavior='unread-count']").text(0)
    )

  handleSuccess: (data) =>
    items = $.map data, (notification) ->
      notification.template

    unread_count = 0
    $.each data, (i, notification) ->
      if notification.unread
         unread_count += 1

    $("[data-behavior='unread-count']").text(unread_count)
    $("[data-behavior='notification-items']").html(items)

jQuery ->
  new Notifications
class Notifications
  constructor: ->
    @notifications = $("[data-behavior='notifications']")

    if @notifications.length > 0
      @handleSuccess @notifications.data("notifications")
      $("[data-behavior='notifications-link']").on "click", @handleClick

    setTimeout (=>
      @getNewNotifications()
    ), 5000

  getNewNotifications: ->
    $.ajax(
      url: "/new_notification_check.json"
      dataType: "JSON"
      method: "GET"
      success: @handleSuccess
    )

  handleClick: (e) =>
    $.ajax(
      url: "/notifications/mark_as_read"
      dataType: "JSON"
      method: "POST"
      success: ->
        $("[data-behavior='unread-count']").text(0)
    )

  handleSuccess: (data) =>
    items = $.map data, (notification) ->
      notification.template

    unread_count = 0
    $.each data, (i, notification) ->
      if notification.unread
         unread_count += 1

    $("[data-behavior='unread-count']").text(unread_count)
    $("[data-behavior='notification-items']").html(items)

    setTimeout (=>
      @getNewNotifications()
    ), 5000        

jQuery ->
  new Notifications

这可以使用promissions/async/await更干净地完成,尽管您可能需要传输JS输出以与浏览器兼容

抽象方法可以在下面的示例中看到

test = ->
  for i in [1,2,3]
    await new Promise (resolve, reject) ->
      setTimeout ->
        console.log(i)
        resolve()
      , 1000

# run asynchronously
setTimeout test

console.log("async loop is running")
运行此脚本按顺序打印每个数字,每个数字之间有1秒的延迟,然后退出

就你的代码而言,没什么不同
$.ajax
支持async/await(),因此您可以将
getNewNotifications
方法更改为

getNewNotifications: ->
  await $.ajax(
    url: "/new_notification_check.json"
    dataType: "JSON"
    method: "GET"
  )
以及构造函数中对此的调用:

setTimeout =>
  loop
    await new Promise (resolve, reject) =>
      setTimeout =>
        results = await @getNewNotifications()
        @handleSuccess(results)
        resolve()
      , 5000

这很好,因为它消除了回调或递归的需要

您是否尝试过在
handleSuccess
中执行
setTimeout
?您不想让我将相同的超时方法添加到success块中吗?在页面加载时调用一次&在调用成功时调用一次?您的方法是什么?我相信,它会创建一个递归调用,正如您所希望的那样。你只要按你的方式叫它一次。然后在
handleSuccess
中再次调用它。当新的
setTimeout
过期时,它将再次调用
handleSuccess
。这将创建一个新的
setTimeout。当新的
setTimeout`过期时,它将再次调用
handleSuccess
。这将创建一个新的“setTimeout”。等等,好的。您能用给定的代码以解决方案的形式编写它来演示吗?我会自己做的,但这是你一天下来的解决办法很好,很乐意帮忙。也可以随意接受。这对未来的搜索者很有帮助。我是只调用一次构造函数,还是再次将代码放入HandleSuccess块中?只有一次(无递归)我得到的Wait没有定义为return Wait(新承诺(…),好的,你可能必须像我说的那样将其传输到浏览器兼容的js。async/Wait是ES2017OK-我现在尝试