JavaScript:有没有一种方法可以使用 Promise 从延迟的限速函数中获取返回值
JavaScript: is there a way to get returned values using Promise from a rate-limited function which got delayed
我有一个这样写的限速器函数
function rateLimter(fn, wait) {
const queue = []
let isCalled = false
const schedule = function () {
const canSchedule = queue.length && !isCalled
if (canSchedule) {
isCalled = true
queue.shift()()
setTimeout(() => {
isCalled = false
schedule()
}, wait)
}
}
return function (...args) {
queue.push(fn.bind(this, ...args))
schedule()
}
}
当我们不需要 returned 值或提供给 rateLimiter
的函数的响应时它工作正常。
我正在尝试重写此 rateLImiter
以向我们提供响应或 returned 值。我想我可以传递一个回调来获得这样的响应
function rateLimter(fn, wait, getResponse) {
const queue = []
let isCalled = false
const schedule = function () {
const canSchedule = queue.length && !isCalled
if (canSchedule) {
isCalled = true
getResponse(queue.shift()())
setTimeout(() => {
isCalled = false
schedule()
}, wait)
}
}
return function (...args) {
queue.push(fn.bind(this, ...args))
schedule()
}
}
但是我试图使用 Promise
来获取值。这是我的尝试
function rateLimter(fn, wait) {
const queue = []
let isCalled = false
const schedule = function () {
const canSchedule = queue.length && !isCalled
if (canSchedule) {
return new Promise((resolve) => {
isCalled = true
resolve(queue.shift()())
setTimeout(() => {
isCalled = false
schedule()
}, wait)
})
}
}
return function (...args) {
queue.push(fn.bind(this, ...args))
return schedule()
}
}
它只对第一次调用有效,但对速率限制函数的任何后续调用不再 return Promise
。有人可以试一试吗?我正在测试的例子是
const logMessageLimited = rateLimter2( async (msg, index) => {
console.log(msg, index)
return index + 10
}, 1000, getResponse)
for (let i = 0; i < 3; i++) {
logMessageLimited(`[Message Log] Action (${i}) rate limited.`, i).then(console.log) // should log out `10` , `11`, `12`
}
我相信这可以满足您的需求。它与您的原始方法基本相同,只是我们 return 一个承诺并另外将承诺的 resolve
处理程序存储在队列中。
function rateLimter(fn, wait) {
const queue = []
let isCalled = false
const schedule = function () {
const canSchedule = queue.length && !isCalled
if (canSchedule) {
isCalled = true
const [fn, resolve] = queue.shift()
resolve(fn())
setTimeout(() => {
isCalled = false
schedule()
}, wait)
}
}
return function (...args) {
return new Promise(resolve => {
queue.push([fn.bind(this, ...args), resolve])
schedule()
})
}
}
const logMessageLimited = rateLimter( async (msg, index) => {
console.log(msg, index)
return index + 10
}, 1000)
for (let i = 0; i < 3; i++) {
logMessageLimited(`[Message Log] Action (${i}) rate limited.`, i).then(console.log) // should log out `10` , `11`, `12`
}
您的方法不起作用,因为您 return 是 schedule
的承诺,但前提是 canSchedule
是 true
(只有第一次调用该函数(在间隔内)。
我有一个这样写的限速器函数
function rateLimter(fn, wait) {
const queue = []
let isCalled = false
const schedule = function () {
const canSchedule = queue.length && !isCalled
if (canSchedule) {
isCalled = true
queue.shift()()
setTimeout(() => {
isCalled = false
schedule()
}, wait)
}
}
return function (...args) {
queue.push(fn.bind(this, ...args))
schedule()
}
}
当我们不需要 returned 值或提供给 rateLimiter
的函数的响应时它工作正常。
我正在尝试重写此 rateLImiter
以向我们提供响应或 returned 值。我想我可以传递一个回调来获得这样的响应
function rateLimter(fn, wait, getResponse) {
const queue = []
let isCalled = false
const schedule = function () {
const canSchedule = queue.length && !isCalled
if (canSchedule) {
isCalled = true
getResponse(queue.shift()())
setTimeout(() => {
isCalled = false
schedule()
}, wait)
}
}
return function (...args) {
queue.push(fn.bind(this, ...args))
schedule()
}
}
但是我试图使用 Promise
来获取值。这是我的尝试
function rateLimter(fn, wait) {
const queue = []
let isCalled = false
const schedule = function () {
const canSchedule = queue.length && !isCalled
if (canSchedule) {
return new Promise((resolve) => {
isCalled = true
resolve(queue.shift()())
setTimeout(() => {
isCalled = false
schedule()
}, wait)
})
}
}
return function (...args) {
queue.push(fn.bind(this, ...args))
return schedule()
}
}
它只对第一次调用有效,但对速率限制函数的任何后续调用不再 return Promise
。有人可以试一试吗?我正在测试的例子是
const logMessageLimited = rateLimter2( async (msg, index) => {
console.log(msg, index)
return index + 10
}, 1000, getResponse)
for (let i = 0; i < 3; i++) {
logMessageLimited(`[Message Log] Action (${i}) rate limited.`, i).then(console.log) // should log out `10` , `11`, `12`
}
我相信这可以满足您的需求。它与您的原始方法基本相同,只是我们 return 一个承诺并另外将承诺的 resolve
处理程序存储在队列中。
function rateLimter(fn, wait) {
const queue = []
let isCalled = false
const schedule = function () {
const canSchedule = queue.length && !isCalled
if (canSchedule) {
isCalled = true
const [fn, resolve] = queue.shift()
resolve(fn())
setTimeout(() => {
isCalled = false
schedule()
}, wait)
}
}
return function (...args) {
return new Promise(resolve => {
queue.push([fn.bind(this, ...args), resolve])
schedule()
})
}
}
const logMessageLimited = rateLimter( async (msg, index) => {
console.log(msg, index)
return index + 10
}, 1000)
for (let i = 0; i < 3; i++) {
logMessageLimited(`[Message Log] Action (${i}) rate limited.`, i).then(console.log) // should log out `10` , `11`, `12`
}
您的方法不起作用,因为您 return 是 schedule
的承诺,但前提是 canSchedule
是 true
(只有第一次调用该函数(在间隔内)。