Chromeless — подождите, прежде чем выполнять инструкции

Я использую Chromeless для получения части информации на веб-сайте и загрузки соответствующего файла:

async function run() {
  const chromeless = new Chromeless()

      const screenshot = await chromeless
        .goto('http://www.website.com')
         title = await chromeless.inputValue('input[name="title"]')

         var fs = require('fs');
         var data = fs.readFileSync(title,"utf8");
         ...
    await chromeless.end()
}

но инструкции по чтению файла выполняются сразу же, когда я запускаю скрипт, и не дожидаюсь завершения веб-сканирования.

В javascript, я думаю, мне нужно будет использовать функции обратного вызова, чтобы предотвратить это, но есть ли лучший способ сделать это с Chromeless?


person Sulli    schedule 12.01.2018    source источник
comment
посмотрите, поможет ли это: github.com/graphcool/chromeless/issues/307   -  person v.coder    schedule 12.01.2018
comment
@v.coder, возможно, это могло бы помочь, но для меня это слишком технично. Я не знаю, что такое событие, что такое контекст... Был бы очень признателен за более простой пример! Или, может быть, можно запустить Chromeless без асинхронности? (Я пришел из Casperjs и у меня не было этой проблемы)   -  person Sulli    schedule 12.01.2018
comment
В приведенном коде отсутствует вызов метода .screenshot(), который необходимо связать с действием .goto(), чтобы сохранить снимок экрана. Кажется, что в целом Chromeless не ждет (ключевое слово await не дает ожидаемого эффекта), если только последний метод в цепочке не возвращает полезное значение, например путь к снимку экрана. (Кроме того, в каждой цепочке может быть только одна такая команда.) Следовательно, оператор await chromeless.inputValue('input[name="title"]') будет выполняться до того, как будет выполнена навигация на веб-сайт.   -  person Otto G    schedule 19.04.2018


Ответы (2)


Вы можете попробовать передать implicitWait: true конструктору Chromeless. По умолчанию это значение равно false. Установка этого параметра на true заставит Chromeless ждать существования элементов перед выполнением команд.

Другими словами, var fs = require('fs'); не должно выполняться до тех пор, пока не будет назначено const title.

async function run() {
  const chromeless = new Chromeless({implicitWait: true})
  const screenshot = await chromeless.goto('http://www.website.com')
  const title = await chromeless.inputValue('input[name="title"]')

  var fs = require('fs');
  var data = fs.readFileSync(title,"utf8");
  ...
  await chromeless.end()
}
person grizzthedj    schedule 03.02.2018
comment
Так вот, я потерял файл, над которым работал, и мне пришлось перекодировать все с нуля. Когда это было сделано, бит require('fs') выполнялся только после присвоения const title даже без implicitWait: true . Понятия не имею почему. Я не смог проверить ваш ответ, но я отмечу его как правильный ответ, так как, похоже, это то, что мне нужно. - person Sulli; 09.02.2018
comment
@Sulli, вероятно, это потому, что вы не пропустили метод .screenshot() после .goto при воссоздании кода. Однако, если бы поле ввода было загружено с помощью AJAX, после загрузки веб-страницы и создания снимка экрана необходимо было бы дождаться элемента, используя либо метод implicitWait, либо метод .wait(), связанный перед методом .inputValue(). - person Otto G; 19.04.2018

Если вы пытаетесь выполнить код за определенное время или по событию, то обратные вызовы являются предпочтительным способом сделать это. Но JS — асинхронный язык. Честно говоря, я не очень им пользуюсь, но кажется, что вы можете просто сделать любой тип асинхронного вызова, и код больше не будет вас блокировать. Просто выделите функцию из вашего задания, которая запускает блокирующую строку, и она должна работать рядом с текущим процессом. Возможно добавление sleep, чтобы убедиться, что он не сохранит ваш другой код. от бега.

person Ponyisasquare    schedule 13.01.2018