Javascript 如何在then()内获得对当前承诺的引用
在下面的代码中,我想检查回调是否从latestRequest执行,因此我正在检查Javascript 如何在then()内获得对当前承诺的引用,javascript,promise,cancellation,Javascript,Promise,Cancellation,在下面的代码中,我想检查回调是否从latestRequest执行,因此我正在检查thisPromise,以查看它是否与latestRequest相同。显然,这个承诺不起作用。有没有办法得到目前的承诺 let latestRequest = MyLib .retrieve(getFilteredQuery(filters, queries, user)) .then(res => { // Checking whether this is the latest request
thisPromise
,以查看它是否与latestRequest
相同。显然,这个承诺不起作用。有没有办法得到目前的承诺
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的请求。我只想更新最新请求的数据。请求可能需要非常不同的时间返回,有时较早的请求稍后返回并覆盖最新的请求。如果您知道处理此问题的好方法,请告诉我。没有获取对承诺对象的引用的方法
。然后从提供的处理程序中调用了。然后
一个建议是为处理程序分配一个序列号,并检查它是否是从闭包中发出的最后一个序列号。未经测试的示例:
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 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
我建议只为每个请求分配一个计数器(在请求范围内的某个地方),并跟踪您从中获得结果的最高计数器,然后您可以忽略任何迟到的旧请求(较低的计数器值)。这似乎也比试图比较承诺要防弹得多。请记住,承诺链由多个承诺组成,因为每次调用newpromise()
或。然后()
创建一个新承诺。这不仅仅是一条链条中的一个承诺。您显示的代码中有多个活动承诺。您的代码中只有一个latestPromise
。请展示创建多个承诺的完整代码。@Bergi我已经包括了简化的示例代码。将该代码视为在一个可以从应用程序中的其他位置调用的函数中。那么,只需保留一个全局latestPromise
和多个本地thisPromise
变量。您在ThereThreak@Bergi中有两个latestRequest
变量,已修复:)如果只有静态属性,请不要使用class
语法class
如果需要,可以使用私有属性进行封装。一个简单的iLife或一个模块作用域也可以做到这一点。无需滥用类
语法作为命名空间。