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 notasync
. – Felix Kling Commented Feb 3, 2020 at 12:41
4 Answers
Reset to default 6the 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 allawait
-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) => { });