await не ждет, пока дочерняя функция будет выполнена первой в react

#javascript #asynchronous #async-await

#javascript #асинхронный #async-await

Вопрос:

 async fetchJobs() {
        this.setState({ isFetching: true }, async () => {
            try{
                debugger;
                console.log("fetching Jobs");
                var body = {
                    page: this.state.page,
                    sortBy: this.state.sortBy,
                    comparator: this.state.comparator,
                    batch: this.state.batch,
                    role: this.state.role,
                    companies: this.state.selectedCompanies
                }
                var job = await axios({
                    method: 'get',
                    url: `${process.env.PUBLIC_URL}/api/page_job?page=${this.state.page}`,
                    params: body
                });
                const page_jobs = job.data.page;
                const jc = job.data.count;
        
                const jobcount = parseInt(jc);
        
                this.setState({
                    jobs: page_jobs,
                    jobcount: jobcount
                }, () => {
                    this.getPagination();
                    if (this.refJobs.current)
                        this.refJobs.current.scrollTop = 0;
                });
                debugger;
                console.log("fetched jobs");
            }
            catch(error){
                console.log("err1");
                throw error;
            }
            finally{
                this.setState({ isFetching: false });
            }
        });    
    }
 
 filterHandler = async (body) => {
        this.setState({
            page: 1,
            sortBy: body.sortBy,
            comparator: body.comparator,
            batch: body.batch,
            role: body.role,
            selectedCompanies: body.selectedCompanies
        }, async () => {
            tr{
               await this.fetchJobs();
               console.log("not catching error");
            }
            catch(error){
                console.log("err2");
                throw error;
            }
        })
    }
 

Когда функция filterHandler вызывается через await, она выдает вывод как:
выборка заданий
, не улавливающих ошибку
, выбранные задания,
вместо:
выборка заданий
, извлеченные задания
, не улавливающие ошибку
Я не могу понять, как использовать async / await для получения желаемого результата. Async / await должен
был остановить родительскую функцию, выполнить дочернюю, а затем вернуться к родительской функции.

Ответ №1:

Когда вы await fetchJobs , вы не ожидаете fetch обещания.

Попробуйте это:

 async fetchJobs() {
  this.setState({ isFetching: true });
  try {
    // ...
  }
  catch(error) {
    // ...
  }
  finally {
    // ...
  }
}
 

Другой вариант — явно сгенерировать и разрешить обещание:

 fetchJobs = () => new Promise( (resolve, reject) => {
  this.setState({ isFetching: true }, async () => {
    try {
      // ...
      debugger;
      console.log("fetched jobs");
      resolve(jobcount); // For example...
    }
    catch(error) {
      // ...
      reject(error);
    }
    finally {
      // Not sure if this is going to be executed, probably not
      this.setState({ isFetching: false });
    }
  });
})
 

Комментарии:

1. Не создаст ли это проблемы, если я удалю обратный вызов из setState, поскольку это может привести к выполнению блока try до завершения seState?

2. Я так не думаю. Первая setState будет выполнена раньше остальных, и ее результаты будут доступны в том же рендеринге, в котором fetch запускается.

3. Я читал, что setStates являются асинхронными по своей природе, и если нам нужно, чтобы после этого выполнялись инструкции, нам нужно поместить их в обратный вызов. Также мне все еще неясно, почему помещение блока try / catch за пределы обратного вызова заставляет его работать. Заранее спасибо 🙂

4. Если это принудительное исполнение от вашего работодателя, тогда используйте явную Promise версию. Если нет, то первая должна пройти нормально.

5. не могли бы вы также объяснить, почему помещение блока try / catch за пределы обратного вызова заставляет его работать?