这个问题在这里已有答案:
我正在尝试从Node中的API调用发回结果数据。我有一个HTML表单,其中设置了搜索栏,该搜索栏会占用搜索字词并触发该字词的搜索。
现在,数据被发送回来并在第一次点击时为空,但是当我再次点击时,前一次调用的数据被发送回我的HTML页面,所以我知道有关于回调的事情。我可以在res.json()上使用setTimeout,但这看起来有点......少年。
我是Node的新手,我知道解决方案很简单......但我似乎无法弄明白。
承诺,回调,异步。也许我对他们去哪里感到有点困惑......
var result;
var Questrade = require("questrade");
var qt = new Questrade("env.KEY")
qt.account = "env.ACCOUNT";
qt.on("ready", function(err) {
if (err) {
console.log(err);
}
});
function searchQt() {
qt.search(searchTerm, function(err, symbols) {
if (err) {
console.log(err);
}
result = symbols;
});
}
app.get("/search", function(req, res) {
searchTerm = req.query.symbol;
searchQt();
res.json(result);
});
我期待按时收到我的数据。
最简单和最增量的解决方案是将res.json(result)
移动到接收result
值的回调。
function searchQt(res) { // <-- note added argument
qt.search(searchTerm, function(err, symbols) {
if (err) {
console.log(err);
}
result = symbols;
res.json(result); // here it is!
});
}
app.get("/search", function(req, res) {
searchTerm = req.query.symbol;
searchQt(res); <-- note added argument
// res.json(result); <-- commented out and moved above
});
你也可以使用promises或async / await,但由于你已经在使用回调,这是获得工作代码的最增量方法。
当你在那里时,你应该从外部范围中删除result
。您不需要或希望在请求之间保留该值。所以只是res.json(symbols);
并完全摆脱results
变量。
并且通过res
作为上面的论点有点代码味道。让我们将qt.search()
的调用直接转移到app.get()
的回调中,以便稍微清理一下。这完全消除了searchQt()
功能:
app.get("/search", function(req, res) {
searchTerm = req.query.symbol;
qt.search(searchTerm, function(err, symbols) {
if (err) {
// handle error here somehow. maybe something like this?
console.log(`An error occurred: ${err}`);
res.status(500).end('An error occurred');
return;
}
res.json(symbols);
});
});
这里还有其他一些改进。 (例如,我不确定在尝试搜索之前是否需要触发ready
事件。因此可能存在竞争条件。)Promises或async / await可能会使这更具可读性。 (人们似乎喜欢那些比深层嵌套回调更好的东西。我个人不介意嵌套,但我明白了。)但这有希望让你朝着正确的方向前进。 (希望我没有添加之前没有的任何错误!)