Ожидание действительно только в функции asyn c с nodejs - PullRequest
2 голосов
/ 03 февраля 2020

Я занимаюсь разработкой приложения для захвата веб-страниц, и кажется, что все функции с asyn c, но консоль показывает ошибку SyntaxError: await is only valid in async function.

Я попытался изменить все функции на asyn c но, похоже, все еще не работает. Это ошибка из-за модуля fs? Я думаю, что когда я попробовал без модуля fs в другом приложении, это на самом деле работает.

Вот мой полный код

const puppeteer = require("puppeteer");
const fs = require('fs');

let galleryName = "frozen"; // Enter gallery name

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  // Adjustments particular to this page to ensure we hit desktop breakpoint.
  page.setViewport({
    width: 1000,
    height: 10000,
    deviceScaleFactor: 1
  });

  fs.readFile('db.txt', function (err, data) {
    if (err) throw err;
    let array = data.toString().split("\n");
    for (i in array) {
      console.log(`Now Processing : ${array[i]} ${array.length - i -1} left`);
      await page.goto(`https://gall.dcinside.com/${galleryName}/${array[i]}`), { // !!!!ERROR shows from here
        waitUntil: "networkidle2",
        timeout: 0
      };
      async function screenshotDOMElement(opts = {}) {
        const padding = "padding" in opts ? opts.padding : 0;
        const path = "path" in opts ? opts.path : null;
        const selector = opts.selector;

        if (!selector) throw Error("Please provide a selector.");

        const rect = await page.evaluate(selector => {
          const element = document.querySelector(selector);
          if (!element) return null;
          const {
            x,
            y,
            width,
            height
          } = element.getBoundingClientRect();
          return {
            left: x,
            top: y,
            width,
            height,
            id: element.id
          };
        }, selector);

        if (!rect)
          throw Error(
            `Could not find element that matches selector: ${selector}.`
          );

        return await page.screenshot({
          path,
          clip: {
            x: rect.left - padding,
            y: rect.top - padding,
            width: rect.width,
            height: rect.height + padding * 2
          }
        });
      }

      await screenshotDOMElement({
        path: `./result/${pageNumArray[i]}.png`,
        selector: ".view_content_wrap",
        padding: 10
      });
    }
  });
  //   // await browser.close();
})();

Ответы [ 4 ]

6 голосов
/ 03 февраля 2020

функция обратного вызова внутри fs также должна быть асин c,

fs.readFile('db.txt', async function (err, data) {}
3 голосов
/ 03 февраля 2020

Ответы, предлагающие сделать обратный вызов async, приведут к исчезновению ошибки, но общая операция readFile не ожидается. Так, например, если вы включите строку с await browser.close();, то browser.close() будет запущен до выполнения обратного вызова readFile.

Когда вы используете обещания, вам лучше использовать Promise API для fs :

const fsPromises = require('fs').promises;

const handle = await fs.readFile('db.txt');
const data = await handle.readFile();
let array = data.toString().split("\n");
// ...etc


await handle.close();

Таким образом:

  • You обратного вызова нет, и вы можете использовать await с файлом и другими асинхронными операциями
  • Возвращенное обещание основной функции async будет выполнено только после выполнения всех await -задач.
2 голосов
/ 03 февраля 2020

функция обратного вызова внутри fs также должна быть асин c

эта часть: fs.readFile('db.txt', async function (err, data)

const puppeteer = require("puppeteer");
const fs = require('fs');

let galleryName = "frozen"; // Enter gallery name

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  // Adjustments particular to this page to ensure we hit desktop breakpoint.
  page.setViewport({
    width: 1000,
    height: 10000,
    deviceScaleFactor: 1
  });

  fs.readFile('db.txt', async function (err, data) {
    if (err) throw err;
    let array = data.toString().split("\n");
    for (i in array) {
      console.log(`Now Processing : ${array[i]} ${array.length - i -1} left`);
      await page.goto(`https://gall.dcinside.com/${galleryName}/${array[i]}`), { // !!!!ERROR shows from here
        waitUntil: "networkidle2",
        timeout: 0
      };
      async function screenshotDOMElement(opts = {}) {
        const padding = "padding" in opts ? opts.padding : 0;
        const path = "path" in opts ? opts.path : null;
        const selector = opts.selector;

        if (!selector) throw Error("Please provide a selector.");

        const rect = await page.evaluate(selector => {
          const element = document.querySelector(selector);
          if (!element) return null;
          const {
            x,
            y,
            width,
            height
          } = element.getBoundingClientRect();
          return {
            left: x,
            top: y,
            width,
            height,
            id: element.id
          };
        }, selector);

        if (!rect)
          throw Error(
            `Could not find element that matches selector: ${selector}.`
          );

        return await page.screenshot({
          path,
          clip: {
            x: rect.left - padding,
            y: rect.top - padding,
            width: rect.width,
            height: rect.height + padding * 2
          }
        });
      }

      await screenshotDOMElement({
        path: `./result/${pageNumArray[i]}.png`,
        selector: ".view_content_wrap",
        padding: 10
      });
    }
  });
  //   // await browser.close();
})();

подробнее здесь о async-await 'https://javascript.info/async-await

1 голос
/ 03 февраля 2020

Вы должны использовать asyn c внутри функции обратного вызова, тогда только вы можете использовать await , иначе вы получите ошибку.

fs.readFile('db.txt', async (err, data) => { });
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...