Не удалось преобразовать очередь обратного вызова для использования обещаний - PullRequest
0 голосов
/ 30 января 2019

Я уже давно использую обещания + асинхронность / ожидание, я думаю, что мне было удобно с ними, но эта ситуация действительно ставит меня в тупик.Будем очень благодарны за любые советы / рекомендации!

Контекст: мое приложение выполняет запросы URI, но мне приходится откладывать каждый запрос на пару секунд.Чтобы сделать задержку более точной, я настроил очередь на выполнение запросов.Нет проблем с использованием обратных вызовов, но я занимался этим некоторое время, и я не могу понять, как справиться с ним с помощью обещаний.

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 => ... )

1 Ответ

0 голосов
/ 30 января 2019

Создайте new Promise в функции addToQueue и поместите функцию распознавателя в очередь.Затем разрешите обещание с результатом выборки:

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()
    }
}

В качестве альтернативы вы можете обещать весь код очереди и использовать обещание в качестве самой очереди.

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 с, чтобы два запроса никогда не выполнялись одновременно, просто изменив

queue = Promise.all([result, queue.then(timer)]).then(res => void res, err => void err);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...