【问题标题】:Returned unirest response in node.js is undefinednode.js 中返回的 unirest 响应未定义
【发布时间】:2016-10-26 18:10:22
【问题描述】:

我正在开发 facebook bot,但我绝不是 node.js 开发人员,这是我第一次使用它,因为我想稍微走出自己的舒适区。

这是我的请求函数

function requestExc() {
    var resDictionary = {} 
    unirest.get("http://openapi.ro/api/exchange/" + queryDict["code"] + ".json")
    .query({"date" : queryDict["date"]})
    .end(function(res) {
        if (res.error) {
            console.log('GET error', res.error)
        } else {
            console.log('GET response', res.body)
            resDictionary["rate"] = res.body["rate"]
            resDictionary["date"] = res.body["date"]
        }
    })

    console.log("resDictionary IS " + resDictionary)
    ///prints resDictionary IS [object Object]
    return resDictionary
}

所以我想得到它的结果

var response = requestExc()
if (response !== null) {
    respondToSender(response, sender)
}

然后采取相应的行动

function respondToSender(res, sender) {
    console.log("RES IS " + res)
    //prints RES IS [object Object]
  if (res["rate"] === null) {
        //do stuff
  }
}

但是当变量到达 respondToSender 时,它始终是未定义的。

 TypeError: Cannot read property 'rate' of undefined

我也尝试过使用 Json.parse() 但它是同一件事。

【问题讨论】:

  • 一方面,您可能应该使用if (response) 而不是if (response !== null);另一方面,这并不能解释为什么它总是未定义。
  • 谢谢,我会更新的!

标签: javascript node.js response unirest


【解决方案1】:

好的,问题是 unirest(像许多 node.js 模块一样)异步工作,这意味着您的代码很可能按此顺序执行:

var response = requestExc() // request is sent first, ok
if (response !== null) {    // this is done second
    respondToSender(response, sender)
}
                            // the response arrived third, when it is not needed

所以要处理这些东西,你必须使用回调/end 方法。见例子here

unirest.post('http://mockbin.com/request')
.query('name=nijiko')
.query({
  pet: 'spot'
})
.end(function (response) {
  console.log(response); // this is where you should use respondToSender
});

console.log(response); 仅在收到回复时才会启动,这就是您想要的。

【讨论】:

  • 我已经做到了。这就是我开始的地方,也是一样。尝试在 .end { return response.body } 中返回,结果是一样的。这就是为什么我试图在外面构建字典,并且只在最后返回它。
  • 我明白了。为了确保这是问题所在,您还可以在 main 中记录 response 并查看这些日志消息的顺序(可能是第一个未定义的对象,第二个对象)。但是对于这种情况,您是什么意思“相同”? responseend 中是未定义的,而它是 requestExc 中的对象?
  • 另一种方式。在.end 中打印或访问时它是一个对象,但在从函数 requestExc 访问值时未定义。
  • @AlexBartiş 所以这就是你应该使用它的方式:在.end 中使用requestExc。你试过吗?
  • requestExc 是执行请求的方法。它会进入一个无限循环。
【解决方案2】:

reddit 的某个人教我如何添加回调,现在它可以按我的意愿工作了。完整代码为:

// GET a resource
function requestExc(callback) {
    unirest.get("http://openapi.ro/api/exchange/" + queryDict["code"] + ".json")
    .query({"date" : queryDict["date"]})
    .end(function(res) {
        if (res.error) {
            console.log('GET error', res.error)
            callback(res.error, null)
        } else {
            console.log('GET response', res.body)
            callback(null, res.body)
        }
    })
}

我称之为

var response = requestExc(function(error, res) {
            console.log("date array is " + dateArray)
            if (error === null) {
                respondToSender(res["rate"], res["date"], sender, queryDict)
            } else {
                sendTextMessage(sender, "Imi pare rau, dar am intimpinat o problema in comunicarea cu BNR")
            }
        })

【讨论】:

  • 是的,这就是我的意思,下面代码中的respondToSender 与回调相同。我希望回复至少是有用的
  • @YakovL 是的,但实际上我并不清楚如何使用回调。但现在我看到了,它真的很简单,而且工作起来很像我们在 swift 中的完成处理程序。谢谢大家的帮助!
【解决方案3】:

我将它包装在 Promise 中以使其正常工作,想知道这是否合适以及是否有帮助?

return new Promise((resolve, reject) => {
   unirest('GET', 'https://url')
       .headers({
           'Accept': 'application/json'
       })
       .send("")
       .then(function (response) {
           if(!response.error) {
               resolve(response)
           } else {
               reject(response)
           }
       })
});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-12-20
    • 1970-01-01
    • 1970-01-01
    • 2021-09-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多