简体   繁体   中英

setting timeout for async function to stop running after x seconds if not done by then

here is simplified version of my code

async function open_tab( setting ){
    const page    = await global_browser.newPage();
    // do stuff 
    page.close();   
}

i want to set a timeout for this function , so i can add a timeout

 setTimeout(function(){page.close() }, 50000);

like

async function open_tab( setting ){
    const page    = await global_browser.newPage();

    setTimeout(function(){page.close() }, 50000);

    // do stuff 
    page.close();   
}

but how can i break the main function (open_tab) so it wouldn't contunue running after timeout ?

**this functions opens a headless browser (chrome puppeteer ) and navigates trough some web pages , sometimes it gets stuck somewhere in navigating for what ever reason and browser remains open for a long time ... i want to break the function and close the tab in these cases ... pleas note i dont want to delay the code in function , i want function to stop running after x seconds if not done by then **

i've tried this

async function open_tab( setting ){
    const page    = await global_browser.newPage();
    await new Promise((resolve, reject) => {
    setTimeout(reject, 50000);
    await page.goto("http://example.com" );
    resolve();
}).then(() => {console.log('done in time!');}).catch(() => {console.log('somethign went wrong !');})
}

but im getting

await page.goto("http://example.com" );
^^^^^
SyntaxError: await is only valid in async function

Just use Promise:

async function open_tab( setting ){
    const page    = await global_browser.newPage();
    await new Promise((resolve, reject) => {
        setTimeout(reject, 50000));
        // do stuff;
        resolve();
        }).then(() => // on time)
        .catch(() => // too long)
        .then(() => page.close());
}

In case you don't need to handle whether your browser is stuck, you can use just resolve():

async function open_tab( setting ){
    const page    = await global_browser.newPage();
    await new Promise(resolve => {
        setTimeout(resolve, 50000));
        // do stuff;
        resolve();
        })
        .then(() => page.close());
}

EDIT: If you need to call async functions inside promise callback, mark that callback async :

async function open_tab( setting ){
    const page    = await global_browser.newPage();
    await new Promise(async (resolve) => {
        setTimeout(resolve, 50000));
        // await do stuff;
        resolve();
        })
        .then(() => page.close());
}

You can move the delay into its own function that returns a promise and await that.

here's a quick example.

function delay(time = 2000) {
  return new Promise((res, rej) => {
    console.log('Delay started');
    setTimeout(() => {
      console.log('Delay running');
      res();
    }, time)
  });
}

async function foo() {
  console.log('Inside foo');
  await delay();
  console.log('Runs after delay');
}

foo();

Repl: https://repl.it/repls/PrevailingLightgreyAssemblylanguage

You can use Promise.delay of bluebird library

const Promise = require('bluebird');

async function main() {
    console.log('Before delay');
    await Promise.delay(1000);
    console.log('After delay');
  }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM