Как я могу заставить оператор ждать, пока предыдущая функция не будет завершена?

#javascript #reactjs #onclick

#javascript #reactjs #onclick

Вопрос:

У меня проблема, когда window.open вызывается слишком быстро, а другая моя функция не завершается и не публикуется вовремя в моей функции onclick.

Я попытался установить тайм-аут для trackData() , но это срабатывало только иногда, и я не хотел устанавливать более длительный тайм-аут.

onClick

    {() => {
       trackData();
       window.open("https:google.com", "_self");
    })
  

есть идеи?

РЕДАКТИРОВАТЬ: следующее работает локально, но не отслеживается в процессе производства. Отслеживание работает КАЖДЫЙ РАЗ, если "_self" заменяется на "_blank" (чего не может быть)

   let postData = async(value) => {
       await tracker({
            action: value,
        })
    }
  

трекер просто создает сообщение axios с действием

    <div
       className="exampleBTN"
       onClick={() =>  {
       postData("example").then(                         
       window.open("https://google.com", 
       "_self")
       )}
    }
    >
   </div>
  

Локально я могу видеть данные, поступающие в базу данных.

Однако в Сети это не работает. Это работает только в том случае, если любое из этих значений истинно:

  • Не имеет window.open в onClick
  • у него нет «_self», но «_blank», поэтому он открывается на новой вкладке

Я подумал, что моя асинхронность была неправильной, поэтому я также попробовал следующее:

  onClick={async () =>  {
 await postData("example").then(                            
 window.open("google.com", "_self"))
 }}
  

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

1. Можете ли вы поделиться большей частью кода? Мы не знаем, что делает TrackData, поэтому мы мало что можем сделать.

2. @pytness, это просто сообщение axios. Это не имеет отношения к вопросу (я считаю, что это так или иначе). TrackData не всегда завершает публикацию перед открытием нового окна. Если я снимаю «window.open» с onClick — это заставляет axios публиковать каждый раз.

Ответ №1:

Вы можете работать с .затем или async / await, чтобы сделать именно это, когда действие приводит к обещанию. Запросы Axios возвращают обещания.

 initiateAsynchronousAction()
  .then(result => console.log(result))
  

Обратный вызов внутри .then функции будет выполнен только в том случае, если обещание выполнено действием, выполняемым асинхронной функцией.

Небольшое уточнение: обратите внимание, что внутри .then() вы должны передать функцию обратного вызова, а не просто немедленно вызвать действия, которые вы хотите выполнить, даже если вы не планируете использовать значение результата. Так что это будет .then(result=> console.log('Inside callback!'))

и не
.then(console.log('Inside callback!'))

Async-await — это еще один способ написать это, это просто синтаксический сахар, то есть просто более простой способ его написания:

 const foo = async () => {
  const result = await initiateAsynchronousAction()
  console.log(result)
}
  

Переменной result будет присвоено значение только после того, как обещание будет выполнено. То есть будет ожидаться присвоение значения.

Вы можете связать a .catch в первом случае или заключить задачу в блок try-catch, чтобы перехватить ошибки, если обещание Axios не выполнено.

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

1. @UnluckyLAD вы могли бы добавить сюда больше кода. Неясно, что делает функция отслеживания. Возвращает ли он обещание? Кроме того, внутри .then() вы должны передать функцию обратного вызова, а не просто немедленно вызвать window.open() , даже если вы не планируете использовать результирующее значение. Так что это будет .then((result)=> window.open())

Ответ №2:

вы можете использовать подход на основе обещаний здесь. используйте aysnc и await для этого.

 async function trackData(){
 ..... 
   let data = awiat your code 
.....
}
  

вызов функции с обещанием

 trackData().then(res=>{
  if(res ==="Success){
 window.open("https:google.com", "_self")
}
})