我怎样在then()中获得对当前Promise的引用

时间:2017-06-29 22:15:19

标签: javascript promise cancellation

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

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的请求。我只希望更新数据以获取最新请求。请求可能需要非常不同的时间才能返回,有时早期的请求会在稍后返回并覆盖最新的请求。如果您知道处理此问题的好方法,请告诉我。

3 个答案:

答案 0 :(得分:1)

.then提供的处理程序中,没有获取对promise对象.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)
  })

答案 1 :(得分:1)

闭包内的实现:

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

答案 2 :(得分:-1)

您只需使用Promise.all即可。发布所有请求并收集承诺。按正确的顺序将它们填入数组并将它们提供给Promise.all。一旦Promise.all的承诺解决,您就可以确定1)他们都得到了回复,2)最新的回复是其中之一,3)最新请求的响应是最后一个已解析数组中的项目。

以上假设请求并行发出,您只想要最后一个请求。对于顺序方法,您需要某种排队机制。