无法将回调队列转换为使用Promise [英] Failing to convert a callback queue to use promises
问题描述
一段时间以来,我一直在使用Promise + async / await,我以为我对它们感到满意,但是这种情况确实让我感到困惑。
I've been using promises + async/await for some time now, I thought I was comfortable with them, but this situation really has me stumped. Any advice/guidance is greatly appreciated!
上下文:我的应用正在发出URI请求,但是我不得不将每个请求延迟几秒钟。为了使延迟更准确,我设置了一个队列来提出请求。使用回调没问题,但是我已经使用了一段时间,而且似乎无法将我的头放在如何使用promises进行实现上。
Context: My app is making URI requests, but I have to delay each request by a couple seconds. To make the delay more exact, I set up a queue for making the requests. No problem using callbacks, but I've been at it for a while, and I can't seem to wrap my head around how to pull it off using promises.
沙盒化了以下的回调代码:
Sandboxed the callback code below:
const queue = []
let t;
function addToQueue(params, cb) {
queue.push({params,cb})
_run()
}
function _run() {
if (!t && queue.length) {
const {params,cb} = queue.shift()
_dummyFetch(params).then( data => cb(data) )
_startTimer()
}
}
function _startTimer() {
t = setTimeout( _endTimer, 2000 )
}
function _endTimer() {
t = null
_run()
}
async function _dummyFetch() {}
沙盒调试:
function seconds() { return Math.round(new Date().getTime()/1000) }
function log(t) { console.log(t + " " + seconds()) }
function logFn(t) { return () => log(t) }
log("init")
addToQueue({}, logFn("request 1")) // should be close/same as init time
addToQueue({}, logFn("request 2"))
addToQueue({}, logFn("request 3"))
// If I could figure out how to make it a promise:
// addToQueue( ... ).then( data => ... )
推荐答案
在 addToQueue 中创建一个
新承诺
code>函数,并将resolver函数放在队列中。然后稍后使用获取结果来解决诺言:
Create a new Promise
in the addToQueue
function and put the resolver function on the queue. Then later resolve the promise with the fetch result:
function addToQueue(params) {
return new Promise(resolve => {
queue.push({params, resolve})
_run()
})
}
function _run() {
if (!t && queue.length) {
const {params, resolve} = queue.shift()
resolve(_dummyFetch(params))
_startTimer()
}
}
或者,您也可以
Alternatively, you can promisify the entire queue code, and use a promise as the queue itself.
const queue = Promise.resolve();
function addToQueue(params) {
const result = queue.then(() => _dummyFetch(params));
queue = queue.then(timer);
return result;
}
function timer() {
return new Promise(resolve => {
setTimeout(resolve, 2000);
});
}
async function _dummyFetch() {}
您甚至可以将队列等待提取时间超过2秒,因此只需简单地更改
You could even make the queue wait for the fetch if it takes longer than 2s, so that two requests never run concurrently, by simply changing
queue = Promise.all([result, queue.then(timer)]).then(res => void res, err => void err);
这篇关于无法将回调队列转换为使用Promise的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!