mirror of
https://github.com/puppeteer/puppeteer
synced 2024-06-14 14:02:48 +00:00
fix: Remove synchronous operation with file system. (#879)
This patch: - introduces `helper.promisify` - a simple polyfill for the `util.promisify`. The `util.promisify` could not be used due to Node6 compatibility issues. - migrates all sync filesystem operations to the async replicas Fixes #884.
This commit is contained in:
parent
7a8aa73466
commit
ff08e45785
@ -15,7 +15,7 @@
|
||||
*/
|
||||
const os = require('os');
|
||||
const path = require('path');
|
||||
const removeSync = require('rimraf').sync;
|
||||
const removeFolder = require('rimraf');
|
||||
const childProcess = require('child_process');
|
||||
const Downloader = require('../utils/ChromiumDownloader');
|
||||
const {Connection} = require('./Connection');
|
||||
@ -26,6 +26,9 @@ const {helper} = require('./helper');
|
||||
// @ts-ignore
|
||||
const ChromiumRevision = require('../package.json').puppeteer.chromium_revision;
|
||||
|
||||
const mkdtempAsync = helper.promisify(fs.mkdtemp);
|
||||
const removeFolderAsync = helper.promisify(removeFolder);
|
||||
|
||||
const CHROME_PROFILE_PATH = path.join(os.tmpdir(), 'puppeteer_dev_profile-');
|
||||
|
||||
const DEFAULT_ARGS = [
|
||||
@ -69,7 +72,7 @@ class Launcher {
|
||||
|
||||
if (!options.args || !options.args.some(arg => arg.startsWith('--user-data-dir'))) {
|
||||
if (!options.userDataDir)
|
||||
temporaryUserDataDir = fs.mkdtempSync(CHROME_PROFILE_PATH);
|
||||
temporaryUserDataDir = await mkdtempAsync(CHROME_PROFILE_PATH);
|
||||
|
||||
chromeArguments.push(`--user-data-dir=${options.userDataDir || temporaryUserDataDir}`);
|
||||
}
|
||||
@ -107,12 +110,16 @@ class Launcher {
|
||||
chromeProcess.stderr.pipe(process.stderr);
|
||||
}
|
||||
|
||||
const waitForChromeToClose = new Promise(fulfill => {
|
||||
const waitForChromeToClose = new Promise((fulfill, reject) => {
|
||||
chromeProcess.once('close', () => {
|
||||
// Cleanup as processes exit.
|
||||
if (temporaryUserDataDir)
|
||||
removeSync(temporaryUserDataDir);
|
||||
if (temporaryUserDataDir) {
|
||||
removeFolderAsync(temporaryUserDataDir)
|
||||
.then(() => fulfill())
|
||||
.catch(err => console.error(err));
|
||||
} else {
|
||||
fulfill();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@ -153,7 +160,7 @@ class Launcher {
|
||||
if (temporaryUserDataDir) {
|
||||
// Attempt to remove temporary profile directory to avoid littering.
|
||||
try {
|
||||
removeSync(temporaryUserDataDir);
|
||||
removeFolder.sync(temporaryUserDataDir);
|
||||
} catch (e) { }
|
||||
}
|
||||
return waitForChromeToClose;
|
||||
|
@ -26,6 +26,8 @@ const {Keyboard, Mouse, Touchscreen} = require('./Input');
|
||||
const Tracing = require('./Tracing');
|
||||
const {helper, debugError} = require('./helper');
|
||||
|
||||
const writeFileAsync = helper.promisify(fs.writeFile);
|
||||
|
||||
class Page extends EventEmitter {
|
||||
/**
|
||||
* @param {!Puppeteer.Session} client
|
||||
@ -655,7 +657,7 @@ class Page extends EventEmitter {
|
||||
|
||||
const buffer = new Buffer(result.data, 'base64');
|
||||
if (options.path)
|
||||
fs.writeFileSync(options.path, buffer);
|
||||
await writeFileAsync(options.path, buffer);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
@ -703,7 +705,7 @@ class Page extends EventEmitter {
|
||||
});
|
||||
const buffer = new Buffer(result.data, 'base64');
|
||||
if (options.path)
|
||||
fs.writeFileSync(options.path, buffer);
|
||||
await writeFileAsync(options.path, buffer);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
@ -13,8 +13,12 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
const fs = require('fs');
|
||||
const {helper} = require('./helper');
|
||||
const fs = require('fs');
|
||||
|
||||
const openAsync = helper.promisify(fs.open);
|
||||
const writeAsync = helper.promisify(fs.write);
|
||||
const closeAsync = helper.promisify(fs.close);
|
||||
|
||||
class Tracing {
|
||||
/**
|
||||
@ -68,14 +72,14 @@ class Tracing {
|
||||
*/
|
||||
async _readStream(handle, path) {
|
||||
let eof = false;
|
||||
const file = fs.openSync(path, 'w');
|
||||
const file = await openAsync(path, 'w');
|
||||
while (!eof) {
|
||||
const response = await this._client.send('IO.read', {handle});
|
||||
eof = response.eof;
|
||||
if (path)
|
||||
fs.writeSync(file, response.data);
|
||||
await writeAsync(file, response.data);
|
||||
}
|
||||
fs.closeSync(file);
|
||||
await closeAsync(file);
|
||||
await this._client.send('IO.close', {handle});
|
||||
}
|
||||
}
|
||||
|
@ -209,6 +209,22 @@ class Helper {
|
||||
static isNumber(obj) {
|
||||
return typeof obj === 'number' || obj instanceof Number;
|
||||
}
|
||||
|
||||
static promisify(nodeFunction) {
|
||||
function promisified(...args) {
|
||||
return new Promise((resolve, reject) => {
|
||||
function callback(err, ...result) {
|
||||
if (err)
|
||||
return reject(err);
|
||||
if (result.length === 1)
|
||||
return resolve(result[0]);
|
||||
return resolve(result);
|
||||
}
|
||||
nodeFunction.call(null, ...args, callback);
|
||||
});
|
||||
}
|
||||
return promisified;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
|
Loading…
Reference in New Issue
Block a user