Lua中基于ngx.location.capture_multi结果,如何通过索引从表中获取正确值?
ngx.location.capture_multi返回值的索引问题 嘿,这个问题我之前也踩过坑,核心是对ngx.location.capture_multi的返回值结构理解出了偏差,我给你捋清楚:
首先,先纠正一个可能的代码小失误:你写的local resps = { ngx.location.capture_multi(reqs), }是把capture_multi的返回结果额外包了一层表,这会让resps变成一个只有1个元素的表(这个元素才是真正包含3个响应的数组)。如果是这种情况,你的循环只会执行一次,而不是三次,所以推测你实际运行的代码应该是去掉了外层大括号的版本:local resps = ngx.location.capture_multi(reqs)——这才是正确的写法。
接下来重点说返回值结构:ngx.location.capture_multi接受一个请求配置的数组(就是你用table.insert塞的那些{url1}这类表),它返回的直接就是一个响应对象的数组——每个元素对应一个请求的结果,这个元素本身就是一个带status、body等字段的表,根本不是嵌套数组!
你之前用resp[1].status会得到nil,原因很简单:循环里的resp就是单个响应对象,它的键是status、body这些字符串,没有数字索引1,所以resp[1]是nil,再访问nil.status自然也是nil。
那如果想用“表索引”的方式获取正确值,有两种完全可行的写法:
1. 用字符串索引替代.语法(本质完全等价)
Lua里resp.status其实是resp["status"]的语法糖,如果你想明确用表索引的形式,可以写成:
local reqs = {} table.insert(reqs, { url1 }) table.insert(reqs, { url2 }) table.insert(reqs, { url3 }) local resps = ngx.location.capture_multi(reqs) for i, resp in ipairs(resps) do print(resp["status"]) -- 和resp.status效果完全一样 end
2. 直接通过resps数组的数字索引访问
既然resps本身就是响应对象的数组,你也可以跳过循环里的resp变量,直接用数组索引定位:
local reqs = {} table.insert(reqs, { url1 }) table.insert(reqs, { url2 }) table.insert(reqs, { url3 }) local resps = ngx.location.capture_multi(reqs) for i = 1, #resps do print(resps[i].status) -- 直接通过resps的索引访问每个响应的status end
总结一下:你之前的错误是把响应对象当成了嵌套表,但实际上它是一个平级的表,status是它的直接字段,不管用.还是字符串索引,都是在访问这个字段的值~
内容的提问来源于stack exchange,提问作者Sukin Sun

