【问题标题】:Refactoring asynchronous CoffeeScript doing AJAX重构异步 CoffeeScript 做 AJAX
【发布时间】:2014-02-23 22:36:06
【问题描述】:

下面的代码可以运行,但我对方法的责任不太满意。我试图保持这些方法肤浅和“单一责任”,但他们仍然做了太多不同的事情 IMO。

在同步世界中,我将有三种方法:

  • 返回响应的doajax(url)
  • parse(response) 返回数据数组
  • 用数组创建图形的draw(data)

但我不知道如何在这种异步情况下执行此操作。任何线索如何重组?会有几个图表,我希望能够用新数据更新给定图表而不创建新数据,所以会有一个类似 updateGraph(graphId, newData) 的方法

doajax = (url) ->
  $.ajax
    url: url
    dataType: 'html'
    success: (response) ->
      parse response

parse = (response) ->
  xmlDoc = $.parseXML(response)
  xml = $(xmlDoc)
  arr = []
  xml.find('S').each ->
    timestamp = new Date($(this).attr('T'))
    value = parseFloat($(this).attr('AI1'))
    arr.push [timestamp, value]
  draw arr

draw = (data) ->
  new Dygraph($('#graph1')[0], data,
  // options..
  )

doajax 'http://api.example.com/stats.xml'

【问题讨论】:

    标签: javascript asynchronous methods coffeescript refactoring


    【解决方案1】:

    使用动态回调,而不是调用其他预定义函数:

    doajax 'http://api.example.com/stats.xml', (xml) -> draw(parse(xml))
    

    或者直接使用$.ajax返回的deferred/promise object,确实可以立即返回:

    doajax = (url) ->
      $.ajax
        url: url
        dataType: 'xml' # or use 'text' for explicitly calling jQuery.parseXML
    
    parse = (xmlDoc) ->
      $(xmlDoc).find('S').map ->
        timestamp = new Date($(this).attr('T'))
        value = parseFloat($(this).attr('AI1'))
        [timestamp, value]
      .toArray()
    
    draw = (data) ->
      new Dygraph($('#graph1')[0], data,
      # options..
      )
    
    doajax 'http://api.example.com/stats.xml'
      .then parse
      .then draw
    

    【讨论】:

    • 这就是我想要的。我已经阅读了有关延迟/承诺的信息,但由于我对 JS 很陌生,因此无法将其应用于我的代码。谢谢伯吉!
    【解决方案2】:

    由于您使用的是 jQuery,因此有一个强大的功能称为 promises,例如 jQuery.Deferred,它也内置在 jQuery.ajax 中

    所以你可以做的是:

    doajax = (url) ->
      $.ajax
        url: url
        dataType: 'xml'
    
    parse = (response) ->
      xml = $(response)
      arr = []
      xml.find('S').each ->
        timestamp = new Date($(this).attr('T'))
        value = parseFloat($(this).attr('AI1'))
        arr.push [timestamp, value]
      draw arr
    
    draw = (data) ->
      new Dygraph($('#graph1')[0], data,
      // options..
    )
    

    并通过像这样链接函数来调用它:

    doajax("/blabla")
        .then(parse)
        .then(draw)
    

    每个函数的返回值将作为参数传递给下一个函数。

    【讨论】:

      猜你喜欢
      • 2017-06-01
      • 1970-01-01
      • 2012-11-02
      • 2012-03-20
      • 2011-09-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多