【问题标题】:Handling async behavior in javascript?处理javascript中的异步行为?
【发布时间】:2019-07-29 19:59:24
【问题描述】:

我在 init 函数的范围之外声明了一些函数,并在 init 中使用参数调用它们。我已经设置了一些控制台日志来跟踪为什么我没有得到想要的结果(即使是错误的)的进度,并注意到它完全跳过了函数声明中的控制台日志。此外,我已经使用 Chrome 的调试器单步执行了脚本,并看到它一到达函数声明的头部,就会跳到 init 中的下一行,而不单步执行函数。

我的想法是这与必须使用回调有关,但目前我不确定。

我已经测试了各种命令,各种形式的函数声明,从在 init 中声明它们到嵌套它们的声明。所有的结果都是一样的,给予或接受。这使我认为编译器将此视为需要更多时间并立即跳到下一行的事情。

这是代码的相关部分。

export default class Fundo extends FlexPlugin {
  constructor(PLUGIN_NAME) {
    super(PLUGIN_NAME);
    this.state = {
      token: "",
      cid: "",
    };
    this.fetchToken = this.fetchToken.bind(this);
    this.fetchCustomer = this.fetchCustomer.bind(this);
  }

  fetchToken = info => {
    const http = require("https");
    http.request(info, res => {
      var chunks = [];
      res.on("data", function(chunk) {
        chunks.push(chunk);
      });
      res.on("end", () => {
        var body = Buffer.concat(chunks);
        var temp = JSON.parse(body);
        this.setState({
          token: "Token " + temp.accessToken,
        });
        console.log(this.token);
      });
    });
  };

  fetchCustomer = (info2, password) => {
    const http = require("https");
    http.request(info2, res => {
      var chunks = [];
      res.on("data", chunk => {
        chunks.push(chunk);
      });
      res.on("end", () => {
        var body = Buffer.concat(chunks);
        var temp = JSON.parse(body);
        var temp2 = temp.items[0].customerId;
        this.setState({
          cid: temp2,
        });
        console.log(this.state.cid);
      });
    });
  };

  init(flex, manager) {
    const options = {
      method: "GET",
      hostname: "hostnamegoeshere.com",
      headers: {
        //api header info
      },
    };
    const options2 = {
      method: "GET",
      hostname: "api.epicloansystems.com",
      headers: {
        //moreheaderinfo
      },
    };
    this.fetchToken(options);
    this.fetchCustomer(options2, this.state.token);
    flex.CRMContainer.defaultProps.uriCallback = cid => {
      console.log("hereD");
      return `https://hostandpath.aspx?cid=${this.state.cid}`;
    };
  }
}

【问题讨论】:

  • 为什么要在构造函数中重新绑定类函数?构造函数不需要知道存在哪些类函数,这就是为什么你已经编写了一个类。只需确保以保留this 的方式调用这些函数,您已经通过使用箭头函数来执行此操作。只需修复你的函数签名:而不是fetchToken = info => { 写普通的fetchToken(info) { 签名。

标签: javascript node.js reactjs


【解决方案1】:

在 JavaScript 中,异步代码(例如发出 HTTP 请求)是非阻塞的,这意味着您为异步代码提供的回调将在未来某个时间点执行。您在http.request 中提供的回调将异步执行。

所以基本上,在您调用this.fetchCustomer 时,this.fetchToken 实际上并没有使用您需要的令牌设置状态!

你需要类似于

的东西
 // not an exact solution here but this is roughly 
 // what the setup would look like if fetchToken returned a promise

this.fetchToken(options).then(() => { this.fetchCustomer(this.state.token) });

了解更多信息的好资源:https://blog.bitsrc.io/understanding-asynchronous-javascript-the-event-loop-74cd408419ff

一般来说,在这里您可以使用Promise 之类的东西来控制相互依赖的异步代码流。

【讨论】:

    猜你喜欢
    • 2013-03-19
    • 2012-04-04
    • 2015-07-28
    • 2012-12-27
    • 1970-01-01
    • 1970-01-01
    • 2020-07-12
    • 2016-12-13
    • 1970-01-01
    相关资源
    最近更新 更多