addEventListener не вызывает API должным образом - PullRequest
3 голосов
/ 01 мая 2020

проблема:

Во-первых, когда я нажимаю кнопку, в консоли ничего не отображается.

Во второй раз, когда я нажимаю кнопку, консоль отображает ответ.

В третий раз, когда я нажимаю кнопку, консоль показывает ответ дважды

ожидания:

, когда я нажимаю кнопку, я ожидаю увидеть ответ, отображаемый в консоли.

Требования

Кнопка может отсутствовать (кнопки являются динамическими c элементами)

  • index. js
import { actionTest } from "./modules/action";

document.addEventListener("DOMContentLoaded", function() {
  actionTest();
});
  • модулей / действий. js
import { fetchApi } from "../store/store";

/**
 * call api
 */
async function fetchData() {
  const res = await fetchApi();
  return res;
}

/**
 * action
 */
export function actionTest() {
  const btnElem = document.querySelector(".test-btn");
  if (btnElem !== null) {
    btnElem.addEventListener(
      "click",
      () => {
        const res = fetchData();
        if (res) {
          console.log(res);
        }
      },
      false
    );
  }
}
document.addEventListener("click", actionTest, false);
  • store / store. js
import axios from "axios";

export async function fetchApi() {
  try {
    const response = await axios({
      method: "get",
      url: "https://jsonplaceholder.typicode.com/todos/1"
    });
    return response;
  } catch (error) {
    return error;
  }
}

Ответы [ 2 ]

3 голосов
/ 01 мая 2020

Мое предложение:

const fetchAPI = () => new Promise(resolve=>resolve("this is data")) //for test

window.onload = () =>{
    console.log("loaded..")
    document.getElementsByClassName("test-btn")[0].onclick = async() =>{
          console.log("clicked")
          const res = await fetchAPI()
          console.log(res)
       }
}
<button class="test-btn">test-button</button>
1 голос
/ 01 мая 2020

Проблема, с которой вы столкнулись, связана с несколькими вещами. Событие, к которому вы изначально привязаны, - DomContentLoaded. Это событие вызывается после загрузки всего содержимого DOM (HTML Text), оно не ожидает завершения загрузки скриптов или таблиц стилей перед запуском. В этом случае вы захотите использовать событие «Загрузить».

document.addEventListener("load", function() {
  actionTest();
});

Это даст вам немедленный первый консольный журнал, когда все скрипты успешно завершат загрузку и будут проанализированы браузером.

Следующая проблема связана с размещением обработчика нажатия кнопки. Каждый раз, когда вы вызываете actiontest (), вы добавляете к кнопке другой, другой обработчик событий.

Вместо этого, возможно, попробуйте что-то вроде этого ...

document.addEventListener("load", function() {
   /* Delegate the event to be captured by the document
      this will ensure that dynamic buttons are captured without 
      having to explicitly assign an event handler to each button
      when it is added to the dom, instead the event will bubble up to the 
      document to be handled.
   */
   document.addEventListener("click", (evt) => {
      if(evt.target.matches('.test-btn')){
          actionTest();
      }
   }, false);


   // execute initial call
   actionTest();
})

export function actionTest() {
  const res = fetchData();
  if (res) {
     console.log(res);
  }
}

Это должно показать только один console.log сначала, а затем один console.log для каждого последующего нажатия на кнопку.

Надеюсь, это поможет!

...