Default params, async await, document.evaluate.Не работает scope в функции завязанной на document.evaluate.Подскажите как пофиксить

const defaultIntervalStepValue = 10; 
const defaultIndividualTimeoutValue = 4000; 

async function searchForElementByXPath(xpath, 
  step_value = defaultIntervalStepValue,
  timeout_value = defaultIndividualTimeoutValue,
  search_scope = document, 
  single_search = false) {

  var step, timeout;

  
  if (single_search) {
    let element = document.evaluate(
      xpath,
      search_scope,
      null,
      XPathResult.FIRST_ORDERED_NODE_TYPE,
      null
    ).singleNodeValue;

    
    return element;
  } else {
    return await new Promise((resolve, reject) => {
      step = setInterval(() => {
        let element = document.evaluate(
          xpath,
          search_scope,
          null,
          XPathResult.FIRST_ORDERED_NODE_TYPE,
          null
        ).singleNodeValue;
        if (element !== null && element !== undefined) {
          clearInterval(step);
          if (timeout_value > 0) clearTimeout(timeout);
          resolve(element);
        }
      }, step_value);

      if (timeout_value > 0) {
        timeout = setTimeout(() => {
          clearInterval(step);
          reject(`Timed out while searching for element with XPath: ${xpath}`);
        }, timeout_value);
      }
    });
  }
}



async function getTitle() {
  let g = await searchForElementByXPath(xpath=`//div[span[.='something']]`);
  console.log(g);

  let h = await searchForElementByXPath(xpath=`//span`, search_scope = g);
  console.log(h);
}

getTitle();

Ответы (2 шт):

Автор решения: vsemozhebuty

Вместо этой строки:

let h = await searchForElementByXPath(xpath=`//span`, search_scope = g);

придётся писать так, если хотите, чтобы у второго и третьего аргументов были значения по умолчанию:

let h = await searchForElementByXPath(xpath=`//span`, undefined, undefined,  g);

Вы не можете в вызове функции присвоить значение сразу четвёртому аргументу по его имени, пропустив предыдущие.

Чтобы не было таких казусов, нужно или менять порядок параметров в объявлении функции, помещая вперёд те, которые чаще будут задаваться, или передавать все аргументы как ключи одного объекта.

Ваш текущий код делает не то, что вы думаете: он создаёт глобальную переменную search_scope, присваивает ей значение g и передаёт его в качестве второго параметра, а в нём функция ждёт step_value, поэтому всё перепутывается.

→ Ссылка
Автор решения: Jhartum

Решение - задаем аргументы функции таким образом:

async function searchForElementByXPath({
  xpath, 
  step_value = defaultIntervalStepValue,
  timeout_value = defaultIndividualTimeoutValue,
  search_scope = document, 
  single_search = false
} = {})

И вызываем функцию так

await searchForElementByXPath({
      xpath : 'random xpath',
      timeout_value : 4000
    });
→ Ссылка