Lua:如何执行从参数传递的回调?

时间:2018-05-31 03:53:01

标签: syntax lua callback

我没有运气就找到了这个问题的答案。我只找到了将回调传递给调用函数的人的例子,但还没有看到调用者如何在内部实际执行回调函数代码。如果有人可以为我提供一个例子和解释,那将非常感激。

我从功能的角度理解回调是如何工作的,我在其他语言中使用过它们。我只是无法弄清楚如何在lua中正确执行它的语法。我正在执行错误的回调参数或将其传递给调用函数错误。

这是我想要做的一些psudocode,只是一个简单的例子,所以我可以看到它的工作。 (我是一个视觉学习者)

callback = function ()
    ... do stuff ...
end

function caller(callback)
    callback()
end

-- run caller function
caller(callback)

修改 我得到了一些答案,说我上面的例子有效,看起来确实如此。谢谢你,但我想我应该更具体,考虑到我的实际代码尽管语法正确但仍无效。

我正在为使用基本模式的FiveM服务器做一些编码。我试图在脚本中使用回调来清理代码,但它似乎没有触发回调函数。这是片段......

客户端脚本:

RegisterNetEvent("parachute:callback")
AddEventHandler('parachute:callback', function(callback)
    print("callback...")
    callback()
end)

服务器脚本:

callback = function ()
    print("callback fired")
    GiveWeaponToPed(GetPlayerPed(-1), GetHashKey("GADGET_PARACHUTE"), 150, true, true)
    SetPedComponentVariation(GetPlayerPed(-1), 5, 1, 0, 0)
end

TriggerEvent('es:addCommand', 'callback', function(source, args, user)
    TriggerClientEvent("parachute:callback", source, callback)
end, {help = "TEST"})

在上面,print("callback...")函数执行但callback()函数没有执行。由于我添加的印刷声明,我可以说出来。

对于那些不熟悉基本模式或FiveM脚本的人的更多上下文,有一个客户端加载的脚本和一个服务器加载的脚本。在服务器中,TriggerEvent('es:addCommand', ... )添加了一个可以使用/<cmd name>执行的命令。 TriggerClientEvent()通过RegisterNetEvent()AddEventHandler()创建的监听器在客户端上启动活动。正如您所看到的,您将回调传递给这些函数,以告诉它们在触发事件时要执行的操作。回调函数本身只是给我的角色降落伞。但是,当我输入/callback时,没有给出降落伞。

如果不是我原先想到的语法会出现什么问题?

2 个答案:

答案 0 :(得分:2)

函数可以是lua中的变量,但它们就像任何其他变量一样。

我不知道你的例子有什么问题,看起来你完全没错。只需输入您的代码即可(try it here)。

<强> 更新

看起来FiveM和essentialmode是客户端/服务器并且在两个不同的执行环境中运行。它们可能为客户端和服务器之间的通信序列化数据,但传递函数不起作用。

使用loadstring()可以做一些事情......这里有一个你可以在jdoodle上运行的例子:

function sayHi(name)
  print("Hello, "..tostring(name).."!")
end

-- create string representation of the function
local functionDef = string.dump(sayHi)

-- convert back to a function
local func = loadstring(functionDef)
func('Jason')

-- or use a string directly, just body, no arguments so
-- we 'return' a function and call it with () after loadstring 
-- to get the returned function - [[ ]] is just syntax for a
-- multiline string
local func2 = loadstring([[
        return function(name) 
          print("Hi there, "..tostring(name).."!")
        end
    ]])()
func2('Jason')

String.dump将现有函数序列化为字符串,loadstring将其转换回函数。您可以在客户端和服务器之间传递此字符串,但它将在其执行的任何环境中执行。你也可以传递一个函数体,但要获取参数,你必须在该体中返回一个带有参数的函数,并调用它来获取返回值以使用该函数。

如果在客户端上执行GiveWeaponToPedSetPedComponentVariation,那么您可以发送这些命令来代替回调&#39;参数并在客户端中使用loadstring ...

客户端

RegisterNetEvent("parachute:callback")
AddEventHandler('parachute:callback', function(callback)
    print("callback...")
    loadstring(callback)()
end)

服务器

codestring = [[
    GiveWeaponToPed(GetPlayerPed(-1), GetHashKey("GADGET_PARACHUTE"), 150, true, true)
    SetPedComponentVariation(GetPlayerPed(-1), 5, 1, 0, 0)
]]

TriggerEvent('es:addCommand', 'callback', function(source, args, user)
    TriggerClientEvent("parachute:callback", source, codestring)
end, {help = "TEST"})

答案 1 :(得分:1)

它将完全按照您的描述工作。您可能希望在回调函数前添加local,但除此之外,您应该很好。这是一个有效的例子:

local callback = function ()
    print("here")
end

function caller(callback)
    callback()
end

-- run caller function
caller(callback)