我为AJAX通知代码开发了一份咖啡脚本。代码本身可以正常工作。我遇到的问题是,我决定使用 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
答案 0 :(得分:2)
我相信您应该能够向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
答案 1 :(得分:0)
尽管您可能必须转换JS输出以使其与浏览器兼容,但这可以使用promises / async / await更加干净地完成。
在下面的示例中可以看到抽象方法。
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
支持异步/等待(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
这很好,因为它消除了对回调或递归的需求