Estoy escribiendo un javascript basado en navegador para raspar el valor de entrada del usuario y proporcionar comentarios. Y en la página, debe hacer clic en diferentes áreas para que se muestre el elemento deseado. Estoy tratando de ver si hay alguna manera de que javascript espere hasta que el elemento regrese antes de comenzar a pasar al siguiente. En este momento solo uso setTimeout, pero tengo que hacer un bucle de todos los elementos que quiero obtener, por lo que las funciones anidadas son desagradables. tratando de ver si hay una solución más elegante. Solía escribir VBA, por lo que no estoy tan familiarizado con la API web asíncrona. aún aprendiendo
function a(){ document.getElementById('1').click() setTimeout(function(){document.getElementById('1a');addmessage;b;}),5000} } function b(){ document.getElementById('2').click() setTimeout(function(){document.getElementById('2a');addmessage;c;}),5000} } function c(){ document.getElementById('3').click() setTimeout(function(){document.getElementById('3a');addmessage;d;}),5000} } function addmessage(){ //this is the function I used to add element do some operation and add to dialog box }etc..
lo que imaginé es como abajo
function addmessage(element_to_click,element_to_collect){ // click element_to_click // wait 5s // collect innertext from element_to_collect // do some operation, generate a message //add message to dialog box }para que pueda hacer algo como
addmessage(1,1a) addmessage(2,2a) <--- this won't execute until the first is complete.Si entiendo la pregunta correctamente, puede comenzar con un envoltorio de promesa alrededor setTimeout :
const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms)); Entonces addMessage podría ser:
async function addMessage(element_to_click, element_to_collect) { element_to_click.click(); await delay(5000); return element_to_collect.textContent; }No dijiste lo que querías hacer con el mensaje de texto, así que lo devolví.
Luego puede escribir un bucle o una serie de llamadas:
async function run() { const a = await addMessage( document.getElementById("1"), document.getElementById("???"), ); const b = await addMessage( document.getElementById("2"), document.getElementById("???"), ); const c = await addMessage( document.getElementById("2"), document.getElementById("???"), ); // ...do something with `a`, `b`, and `c`... } Cuando llame a run , no olvide manejar el rechazo de la promesa (en caso de que algo salga mal).
Ha dicho que después del clic, "... la página necesita unos segundos para cargarse..." Los tiempos de espera codificados son frágiles y, a menudo, se rompen. En lugar de un tiempo de espera, intente conectarse a algo que cambiará, tal vez a través de un MutationObserver en el elemento del que está "recopilando".
Puede hacer que su código espere a que se complete un tiempo de espera envolviéndolo en una Promise y usando el patrón de async await :
// Return a new Promise immediately, that completes at the end of the timeout function addmessage(element_to_click, element_to_collect) { return new Promise((resolve, reject) => { // do whatever // resolve the Promise after 5s setTimeout(resolve, 5000) // you can also resolve the Promise on any other event, like user input // (or use `reject` when an error occurs) // you can pass a return value to `resolve` like resolve(input.value) }) } // `async` functions also return a Promise immediately async function addMessages() { // `await` will block until Promise completes and // returns the resolved value to be used synchronously within the async func const in1 = await addmessage('1', '1a') const in2 = await addmessage('2', '2a') const in3 = await addmessage('3', '3a') } addMessages()