6

这是我在https://github.com/kripken/lua.vm.js/issues/5提出的一个问题,我想提交给 stackoverflow。鉴于较高的曝光率,我可能会在这里得到更快的答案。为了确保清楚地理解我的问题,我将重申它。如何从以下示例中获取回调数据?

提交的问题:

(lua.vm.js 是一个)非常棒的软件,在浏览器中替代 JavaScript 的潜力巨大!

从邮件列表、wiki、问题等中收集的一些代码片段。一切都是开箱即用的,不会对性能产生任何影响。我只对 JQuery ajax 调用和 WebSocket 返回消息的回调返回值有问题。

例如(参见下面的 script_example.html):

js.run('$.get("/glossary.json", function(data) { console.log(data); });') -- this works
jq.get("/glossary.json", function(data) print(data) end) -- the callback is firing, but data is not returned

使用 load() 函数的解决方法:

jq('#result').hide().load("/glossary.json", function() print(jq('#result').html()) end) -- this works because after the callback is fired, we just collect the result from the result div

以下进入 script_example.html(参见 lua.vm.js git 存储库):

<!-- begin script tag example -->

<script src="lua.vm.js"></script>
<script src="jquery-1.10.1.js"></script>

<!--
    Simplest web server for serving static files
    python -m SimpleHTTPServer 8080
-->

<script type="text/lua">
-- Print contents of `tbl`, with indentation.
-- `indent` sets the initial level of indentation.
function tprint (tbl, indent)
  if not indent then indent = 0 end
  for k, v in pairs(tbl) do
    formatting = string.rep("  ", indent) .. k .. ": "
    if type(v) == "table" then
      print(formatting)
      tprint(v, indent+1)
    else
      print(formatting .. tostring(v))
    end
  end
end

-- function test()
--   return 'ok'
-- end
-- for i=1,5 do
--   js.global.alert(test())
-- end

local jq = js.get("$")
-- jq('body').append("plop").click(function() js.global.alert("plop click") end)
-- local version = jq().jquery
-- js.global.alert(version)
-- jq('#result').load("/glossary.json")
jq('#result').hide().load("/glossary.json", function() print(jq('#result').html()) end)
-- jq.get("/glossary.json", function(data) print(data) end) -- callback is firing, but    data is not returned
-- js.run('$.get("/glossary.json", function(data) { console.log(data); });')

-- local ws = js.new.WebSocket("ws://echo.websocket.org/?encoding=text")
-- ws.onopen = function()
--   print("connected!")
--   ws.send("Rock it with HTML5 WebSocket")
-- end
-- ws.onclose = function()
--   print("disconnected")
-- end
-- ws.onerror = function(error)
--   print(error)
-- end
-- ws.onmessage = function(e)
--   tprint(e) -- using tprint() because an empty table is returned instead of the message
--   ws.close()
-- end
</script>

<!-- end script tag example -->

<div id="result"></div>

上面示例中加载的glossary.json 文件:

{
  "glossary": {
    "title": "example glossary",
    "GlossDiv": {
        "title": "S",
        "GlossList": {
            "GlossEntry": {
                "ID": "SGML",
                "SortAs": "SGML",
                "GlossTerm": "Standard Generalized Markup Language",
                "Acronym": "SGML",
                "Abbrev": "ISO 8879:1986",
                "GlossDef": {
                    "para": "A meta-markup language, used to create markup languages such as DocBook.",
                    "GlossSeeAlso": ["GML", "XML"]
                },
                "GlossSee": "markup"
            }
        }
    }
  }
}
4

1 回答 1

2

抱歉,我刚刚意识到我忘了回来报告解决方案。

从 jQuery 1.5 开始,所有 jQuery 的 Ajax 方法都返回 XMLHTTPRequest 对象的超集。这个由 $.get() 返回的 jQuery XHR 对象或“jqXHR”实现了 Promise 接口,为它提供了所有的属性、方法、...

例如,它包含 responseText 和 responseXML 属性,以及 getResponseHeader() 方法。

基于此,以下代码起作用并返回回调数据(responseText):

local jq = js.get("$")
local jqxhr = jq.get("/glossary.json")
jqxhr.done(function() print(jqxhr.responseText) end)

也可以使用直接的 XMLHTTPRequest 包装函数完全绕过 jQuery:

local xhr = function(method, url, callback)
  local xhr = js.new.XMLHttpRequest()
  xhr.onreadystatechange = function()
    if xhr.readyState == 4 and xhr.status == 200 then
      return callback(xhr.responseText)
    end
  end
  xhr.open(method, url)
  xhr.send()
end

xhr("GET", "/glossary.json", function(data) print(data) end)
于 2013-07-08T10:51:01.450 回答