在显示接收数据之前等待函数在节点中完成[重复]

问题描述 投票:0回答:1

我正在尝试从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);
});

我期待按时收到我的数据。

javascript node.js callback
1个回答
1
投票

最简单和最增量的解决方案是将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可能会使这更具可读性。 (人们似乎喜欢那些比深层嵌套回调更好的东西。我个人不介意嵌套,但我明白了。)但这有希望让你朝着正确的方向前进。 (希望我没有添加之前没有的任何错误!)

© www.soinside.com 2019 - 2024. All rights reserved.