【问题标题】:Typescript Promise with JQuery seems to run twice?带有 JQuery 的 Typescript Promise 似乎运行了两次?
【发布时间】:2019-05-21 10:34:24
【问题描述】:

我以为我正在慢慢掌握 Typescript/JS 中的 Promises,但这让我感到困惑。

我正在尝试使用 Promises 等待两个 JQuery getJSON 请求完成。使用我的浏览器 - 访问本地服务器 - 一切正常:但是我从用户那里获得了 HAR 日志,显示 getJSON 请求重复,并且 Promise 解析了两次。我根本无法重现这种行为,但对于用户来说,它是一致的,使用禁用插件的 Chrome 71。

我希望控制台输出是这样的......

   Document Ready
   File Loaded
   Query Loaded
   Got file and query

但相反 - 在这台用户机器上,它更像这样

   Document Ready
   File Loaded
   Query Loaded
   File Loaded
   Query Loaded
   Got file and query
   Got file and query

这里是稍微简化的代码。

class Panel {
  private pathName: string;

  constructor(name: string) {
    this.pathName = name;
  }

  async loadStuff(buster: string): Promise<any> {
    // start to fetch the file JSON. 
    let fileP = $.getJSON(this.pathName + "/file.json", { mtime: buster });

    // start to run the query
    let queryP = $.getJSON("/api/query");

    return fileP.then(async (data: any) => {
      console.log("File loaded");
      this.dosomething(data.objects);

      return queryP.then((qdata: any) => {
        console.log("Query loaded");
        this.dosomethingelse(qdata);
      });
    }
      , () => {
        alert("Error loading '" + this.pathName + "/file.json'");
      });
  }
}

$(() => {

  console.log("Document ready");

  let bp: Panel = new Panel("foo");  
  let promise: Promise<void> = bp.loadStuff("test");

  promise.then(() => {
    console.log("Got file and query");
  });

我最好的猜测是我对仅由于用户计算机上的网络时间条件而触发的 Promise 做错了什么。但我不知道是什么!

【问题讨论】:

  • 您是否查看了来自/api/query 的实际响应消息?这个“用户”是否得到相同的确切响应?还是这里涉及身份验证?这个 JS 如何被执行或附加到文档中?你会因为布局而绑定多个事件吗?
  • @AussieJoe 响应在 HAR 文件中看起来非常好。没有身份验证问题。
  • 起初我虽然可能是 Jquery 文档准备好触发两次,但控制台日志只有一次“文档准备就绪”。

标签: jquery typescript promise getjson


【解决方案1】:

这可能不是一个直接的答案,但如果你等待你的承诺,它会更容易推理你的代码。

class Panel {
  private pathName: string;

  constructor(name: string) {
    this.pathName = name;
  }
  async loadStuff(buster: string): Promise<any> {
    try {
      // start to fetch the file JSON.
      let fileP = await $.getJSON(this.pathName + '/file.json', {
        mtime: buster,
      });
      this.dosomething(fileP.objects);

      // start to run the query
      let queryP = await $.getJSON('/api/query');
      this.dosomethingelse(queryP);
    } catch (e) {
      alert("Error loading '" + this.pathName + "/file.json'");
    }
  }
}

【讨论】:

  • 值得一试,但这消除了我希望提高性能的两个 getJSON 请求的重叠。
  • 您可以使用let [filep, queryp] = await Promise.all([ &lt;your get JSON&gt;]) 并行执行。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-13
  • 2015-05-12
  • 2021-10-17
  • 2015-04-07
  • 2013-02-04
相关资源
最近更新 更多