Установить время ожидания в инструментах отладки Chrome - PullRequest
0 голосов
/ 02 ноября 2019

Я пытаюсь запустить скрипт в инструментах отладчика Chrome. Внутри скрипта я бы хотел подождать (например, кнопка после рендеринга анимации). Как я могу это сделать? Я нашел несколько таких решений:

async function test () {
    console.log('1');
    await setTimeout(function() {
        console.log('2');
    }, 3000);
    console.log('3');   
}

Я ожидал напечатать 1, 2 и через три секунды 3. Но результат равен 1,3, а затем 2 через три секунды.

Iхотел бы сделать это для нескольких последовательных действий.

Есть идеи, как мне это сделать?

Ответы [ 3 ]

1 голос
/ 02 ноября 2019

Вы не можете await результат функции setTimeout, потому что это не Promise. Чтобы сделать то, что вы хотите, вы можете создать Promise, который разрешается через 3 секунды, вот пример:

async function test() {
  console.log('1');
  console.log('2');
  await new Promise(resolve => {
    setTimeout(resolve, 3000);
  });
  console.log('3');
}

test();

Из вашего описания кажется, что вы хотите получить доступ к некоторым элементам DOM, когда они станут доступны, для этого есть MutationObserver , вот пример:

const parent = document.querySelector('#parent');

setTimeout(() => {
  const button = document.createElement('button');
  button.textContent = 'BUTTON';
  button.id = 'targetBtn';
  parent.appendChild(button);
}, 2000);

const observer = new MutationObserver((mutationList) => {
  mutationList.forEach((mutationRecord) => {
    if (mutationRecord.addedNodes && mutationRecord.addedNodes.length) {
      const btn = [...mutationRecord.addedNodes].find(n => n.matches && n.matches('#targetBtn'));
      if (btn) {
        console.log('Button #' + btn.id + ' was found');
      }
    }
  });
});
observer.observe(parent, {
  childList: true
});
<div id="parent">
</div>

Для этого нужно отслеживать дочерний список #parent элемента, чтобы видеть, когда добавляется элемент #targetBtn.

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

0 голосов
/ 02 ноября 2019

Как уже упоминалось, await ждет обещания, которое будет решено или отклонено. setTimeout не возвращает Promise и, следовательно, выполнение переходит к следующей строке, которая выводит 3. Полезное чтение: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function

С точки зрения ожидания элемента, это зависит от того, какую платформу вы используете,Для обычного JavaScript вы можете вызвать пользовательское событие в дополнение к отображению кнопки. У React есть способы, с помощью которых вы можете инициировать действия, основанные на определенных изменениях реквизита.

0 голосов
/ 02 ноября 2019

Я думаю, вы задаете два разных вопроса. Один вопрос о том, как ждать, пока элемент станет DOM, и другой вопрос о том, как асинхронные действия работают в JavaScript.

Для ожидания отображения элемента DOM, самое простое решение (на мой взгляд)чтобы создать цикл while и разорвать его, как только элемент существует:

// NOTE: this code isn't tested nor I have tried to see if it works

let elem = document.querySelector('.someSelector');

while(!elem) {
  elem = document.querySelector('.someSelector');
}

// do something else when the element shows

Имейте в виду, что это может вызвать проблемы с утечкой памяти.

Я ожидал напечатать 1, 2и через три секунды 3.

Ваше ожидание неверно. Способ работы setTimeout состоит в том, что он добавляет вашу функцию обратного вызова в отдельный стек и вызывает ее по истечении заданного вами количества миллисекунд. Если вы хотите показать три через 3 секунды, вам нужно будет сделать:

function test() {
  console.log('1');
  console.log('2');
  setTimeout(function() {
    console.log('3');
  }, 3000);
}

Или использовать async / await

async function test() {
  console.log('1');
  console.log('2');
  await new Promise(resolve => {
    setTimeout(resolve, 3000);
  });
  console.log('3');
}
...