0

У меня есть обработчик событий, который при отлавливании определенного тега в xml вызывает обратную функцию. В обратной функции я выполняю операции сложения и сравнения , затем записываю данные в MongoDB с помощью Mongoose. Обработчик в мгновение срабатывает 10 раз и, соответственно вызывает 10 функций. В консоле я наблюдаю, что сначала выполняются "операции сложения и сравнения", для каждой вызванной функции, а только затем идет 10 подряд записей в MongoDB. Как мне задержать исполнение следующий сallback-функций, пока не воспроизведется запись в Mongo, т.е пока не выполнится весь необходимый код в первом сallback?

Пример кода:

    xmlStream.on('tag:offer', async function (offer) {
        let difference = offer.oldprice - offer.price;
        console.log(difference);
        if (difference > 0){
            await Raw_data.create({price: +offer.price});
        }
    })

Сначала вывод ВСЕХ difference, а затем уже запись всех документов в базу

  • запустите метод, в коллбэке или промисе метода записи – Dmytro Aug 31 '19 at 17:33
  • @Дмытрык, так он и так сейчас в колбеке. – Dmitry Filippov Aug 31 '19 at 17:55
  • 1
    Попробуйте создать глобальную переменную isLoading = false; и в теле синхронной функции переназначать её в true, а когда получен результат из await Raw_data.create({price: +offer.price}) сделать проверку и перезаписать переменную опять на false. Начинать выполнение коллбэка только при значении переменной false – Alexander P Sep 01 '19 at 07:44
  • А вообще, вы желаете чтобы асинхронный код выполнялся синхронно, есть возможность это сделать лишь блокируя всё приложение - те же лоадеры на сайтах. Смысл асинхронности в ускорении работы приложения посмотрите хотя-бы на Youtube, вы же не ждёте, пока все остальные оставят комментарий. Есть лишь два пути: отобразить устаревшую информацию до окончания выполнения асинхронного кода (обновления компонента) или блокировать всё приложение (в случае больших приложений - недопустимо) – Alexander P Sep 01 '19 at 08:13
  • Alexander P, а в случае написания парсера?) В общем буду записывать данные колбеков во внешний объект, в очередь и потом по очереди их исполнять – Dmitry Filippov Sep 02 '19 at 08:27

1 Answers1

1

На сколько я понимаю суть, тут может быть несколько вариантов:

  • вы должны управлять xml потоком, т.е. получили тэг, поставили поток на паузу, обработали, пошли дальше.

  • данные которые вы обрабатываете, попробуйте отдавать в следующий поток. А в нём по мере поступления данных либо складывайте в очередь, либо сразу вставляйте в монгу. Тут вы точно можете управлять потоком. Нужно , чтобы xmlstream был transform stream и можно было управлять передачей данных.

  • можете создать кэш и складывать туда все данные для вставки. А после завершения потока вставить сразу все вместе.

  • да, я ставлю поток на паузу во время того когда вызывается первый кол бек, но все равно успевает проскочить порядка 10-40 тегов и вызываются другие колбеки. Спасибо за совет! Только не очень понятно как реализовать 2-ой вариант – Dmitry Filippov Sep 05 '19 at 08:56
  • А если складывать в очередь(объект) нужные данные, а потом уже их потоком обработать, то это не скажется негативно на ресурсах? Допустим если xml пол гига? – Dmitry Filippov Sep 05 '19 at 09:03
  • 1
    Скажется, именно поэтому нужно обрабатывать данные по мере поступления. Во втором варике вставка происходит внутри Writable или Transform stream. Во Writable переопределяете _write, там делаете работу по вставки и т.д. – ReklatsMasters Sep 06 '19 at 14:32