如何在 then() 中获取对当前 Promise 的引用

How do I get a reference to the current Promise within then()

在下面的代码中,我想检查回调是否从 latestRequest 执行,所以我检查 thisPromise 看它是否与 latestRequest 相同。显然 thisPromise 是行不通的。有没有办法获得当前的Promise?

let latestRequest = MyLib
  .retrieve(getFilteredQuery(filters, queries, user))
  .then(res => {
    // Checking whether this is the latest request handler
    if (latestRequest === thisPromise) {
      updateData(res)
    }
  })
  .catch(err => {
    console.error(err)
  })

我的用例是处理来自 API 的请求。我只想为最新请求更新数据。这些请求与 return 所用的时间可能有很大不同,有时较早的请求会稍后返回并覆盖最新的请求。如果你知道处理这个问题的好方法,请告诉我。

没有方法获取对承诺对象的引用 .then 是从 .then 提供的处理程序中调用的。

一个建议是为处理程序分配一个序列号,并在闭包中检查它是否是最后一个发出的。未经测试的示例:

let latestRequestId = 0;

let checkLatest = ()=> {
    let thisRequest = ++latestRequestId;
    return (res=>{
    // Checking whether this is the latest request handler
    if (latestRequestId === thisRequest) {
      updateData(res)
    }
  })
}

let latestRequest = MyLib
  .retrieve(getFilteredQuery(filters, queries, user))
  .then(checkLatest())
  .catch(err => {
    console.error(err)
  })

闭包内的实现:

const run = (() => {
  let currentPromise;

  return () => {
    const p = new Promise((resolve, reject) => {
      // run an asynchronous process and resolve like resolve(results)
    })
    .then(results => {
      if (p === currentPromise) {
        // process results here
      }
    })

    currentPromise = p;
  }
})()

使用 class 的类似替代方法:

class Request {
  static #currentPromise;

  static run() {
    const p = new Promise((resolve, reject) => {
      // run an asynchronous process and resolve like resolve(results)
    })
    .then(results => {
      if (p === Request.#currentPromise) {
        // process results here
      }
    })

    Request.#currentPromise = p;
  }
}

您可以通过实施模拟延迟来进行测试:

const run = (() => {
  let currentPromise;

  return (timeout) => {
    const p = new Promise((resolve, reject) => {
      setTimeout(_ => resolve(timeout), timeout);
    })
    .then(data => {
      if (p === currentPromise) {
        console.log('latest request', data);
      }
    })

    currentPromise = p;
  }
})()

run(1000); // 1s request
run( 500);
run(  10); // last request, 0.1s