最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Await is only valid in async function with nodejs - Stack Overflow

programmeradmin1浏览0评论

I'm developing a web capture app and it seems that all the functions are with async but console shows me a SyntaxError: await is only valid in async function error.

I tried to change all the functions to async but it seems still not working. Is it an error because of the fs module? I think when I tried without fs module in another app it actually works.

Here's my full code

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(`/${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();
})();

I'm developing a web capture app and it seems that all the functions are with async but console shows me a SyntaxError: await is only valid in async function error.

I tried to change all the functions to async but it seems still not working. Is it an error because of the fs module? I think when I tried without fs module in another app it actually works.

Here's my full code

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./${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();
})();
Share Improve this question edited Feb 3, 2020 at 12:44 sameera lakshitha 1,9814 gold badges23 silver badges29 bronze badges asked Feb 3, 2020 at 12:40 writingdeveloperwritingdeveloper 1,0764 gold badges25 silver badges52 bronze badges 1
  • 5 The function you pass to fs.readFile is not async. – Felix Kling Commented Feb 3, 2020 at 12:41
Add a ment  | 

4 Answers 4

Reset to default 6

the callback function inside fs needs to be async as well,

fs.readFile('db.txt', async function (err, data) {}

The answers suggesting to make the callback async will make the error disappear, but the overall readFile operation will not be awaited. So, if for instance, you would enable the line with await browser.close();, that browser.close() will run before the readFile callback executes.

When you use promises, you are better off using the Promise API for 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();

This way:

  • You don't have a callback, and you can use await with the file and other asynchronous operations
  • The main async function's returned promise will only resolve when all await-tasks have been performed.

the callback function inside fs needs to be async as well

this part : 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./${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();
})();

read more here about async-await' https://javascript.info/async-await

You have to use async inside callback function then only you can able to use await otherwise you'll get the error.

fs.readFile('db.txt', async (err, data) => { });
发布评论

评论列表(0)

  1. 暂无评论