簡體   English   中英

如何與CoffeeScript重新同步setTimeout()? 滑軌5

[英]How to resynchronize setTimeout() with CoffeeScript? Rails 5

我為AJAX通知代碼開發了一個coffeescript。 代碼本身可以正常工作。 我遇到的問題是,我決定使用setTimeout()而不是setInterval()來避免耗盡線程並導致嚴重的擁塞。 我很少用過coffeescript,我需要幫助弄清楚如何正確地循環setTimeout函數。 在setTimeout成功使用getNewNotifications()方法接收數據之后,如何調用遞歸方法調用?

notifications.coffee

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

我相信您應該能夠將setTimeout添加到handleSuccess ,這將創建您要查找的遞歸調用:

notifications.coffee

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

可以使用promises / 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( guide ),因此您可以將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

這很好,因為它消除了對回調或遞歸的需要

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM