Vueresource ожидает завершения предыдущего http-запроса, а затем выполняет следующий запрос - PullRequest
0 голосов
/ 06 сентября 2018

Пытаюсь загрузить большой набор данных и разбить его, выбирая данные с небольшими интервалами

Так что это

Предположим, у меня есть 1000 записей, и я хотел бы получать данные с шагом 10, но запрашивать следующие 10 только после завершения текущего запроса

так что в настоящее время это то, что я делаю, но это делает несколько запросов HTTP, и я не могу знать, когда один завершен или нет

  processData(){
    this.fetchedtrucks = 0;
    this.dataLoadingCmplete = false;
    this.exportstart = true;
    this.ttatdatatrucks = [];
    let i = 0;
    do {
        const page = (i == 0) ? 0 : (i / (this.paginatorval));
        //send http request

          this.$http.get("v1/data-trucks",
                {
                    from: this.duration_from,
                    to: this.duration_to,
                    page: page,
                    pagination: this.paginatorval,
                    filters: this.filters,
                    only_completed: this.only_completed,
                    non_reg: this.non_reg
                }
            ).then(
                res => {
                    this.ttatdatatrucks = this.ttatdatatrucks.concat(this.getTransformedData(res.ttatdata));
                    this.fetchedtrucks += this.paginatorval;
                    if (this.fetchedtrucks >= this.totalRecords) {
                        this.dataLOadingCompleted();
                    }


                }, err => {
                    this.fetchedtrucks += this.paginatorval;
                    this.errorloadingdata = true;
                }
            )

        i += this.paginatorval;

    } while (i < this.totalRecords);

Вышеописанное работает, но не очень аккуратно, так как, когда я проверяю средства разработки браузера, я вижу более 100 выданных http-запросов, и я с нетерпением жду, чтобы выполнить следующий http-запрос, только когда текущий запрос завершен

Как мне этого добиться?

1 Ответ

0 голосов
/ 06 сентября 2018

Причина, по которой это происходит, в том, что ваш цикл do.. while запускает все http-запросы одновременно. Это не касается вашего обещания, так как оно определяется внешне.

Без рефакторинга большей части вашего кода, самый простой способ решить эту проблему - использовать ключевое слово JavaScript async / await. Я продемонстрирую это решение, но если вы не сможете использовать эти операторы, я опишу, как выполнить рефакторинг вашего кода, чтобы получить то, что вы хотите.

Первый простой способ: вам нужно сделать processData асинхронным, чтобы вы могли поместить в него оператор ожидания. Это можно сделать, добавив ключевое слово async в объявление processData, например:

async processData() {...

Далее вам нужно удалить оболочку .then и использовать вместо нее оператор await. Ваш код внутри do.. while будет выглядеть так:

     try {
            const res = await this.$http.get("v1/data-trucks",
                {
                    from: this.duration_from,
                    to: this.duration_to,
                    page: page,
                    pagination: this.paginatorval,
                    filters: this.filters,
                    only_completed: this.only_completed,
                    non_reg: this.non_reg
                }
            )
            this.ttatdatatrucks = 
            this.ttatdatatrucks.concat(this.getTransformedData(res.ttatdata));
            this.fetchedtrucks += this.paginatorval;
            if (this.fetchedtrucks >= this.totalRecords) {
                this.dataLOadingCompleted();                    
     } catch (err) {
             this.fetchedtrucks += this.paginatorval;
             this.errorloadingdata = true;
     }

Этот код заставит ваш цикл do while работать долго, но он будет соответствовать вашему требованию ожидания завершения каждого http-запроса для выполнения следующего.

Теперь, если оператор await недоступен, вам нужно покончить с циклом do ... while. Я не думаю, что вы могли бы легко сделать эту работу. Я обрисую, что вам нужно сделать вместо этого.

1) удалить цикл do ... while

2) добавьте вашу переменную i и любые другие соответствующие переменные в качестве параметров в ваш цикл processData

3) рекурсивно вызывать processData () из блока .then вашего http-запроса

4) не забудьте добавить соответствующую логику в вашу функцию для выхода из рекурсии

это будет выглядеть примерно так:

processData(i, complete) {
 if (i >= complete) return;
 this.$http.get()...
 .then(res => {
    //do processing and stuff
    i++
    processData(i, complete)
})

это не настоящая рекурсия, я думаю - это всего лишь попытка ... хотя она и замаскирована под рекурсию, но она достигнет результата, который вы после этого получите, - синхронных HTTP-запросов

...