3

マイクロソフトの新しいヘッドレス ブラウザ プレイライトで遊んで、エラーも何も返さないものを構築しました。

現時点で、私のアイデアは終わりです。私の失敗を指摘するためのヒントをいくつかお願いします。

このコードは、複数のヘッドレス ブラウザー グループの非同期を開始するだけです。しかし、ブラウザの起動がハングし、アプリケーションは無限ループのままになります。ここにコードを貼り付けます。動作を再現するための単純な nodejs スクリプトです。

助けて読んでくれてありがとう;)

const playwright = require('playwright');

log('start playwright async');

let maxRunners = 1;
let running = 0;
let list = [1,2,3,4,5,6,7,8,9,0,11,12,13,14,15];

log('start job');

while (list.length > 0) {

    if (running < maxRunners) {
        log('runner started');
        running++;

        let entry = list[0];
        list.shift();

        log('start browser loop');
        for (const browserType of ['chromium', 'firefox', 'webkit']) {
            log('fire async');
            (async () => {
                log('loop next');
                log('launch: ', browserType);
                const browser = await playwright[browserType].launch({
                    headless: false
                });
                log(browserType, ' launched');
                const context = await browser.newContext();
                log('open new page');
                const page = await context.newPage('http://whatsmyuseragent.org/');
                log('page opened');
                log('make screenshot');
                await page.screenshot({path: `example-${browserType}.png`});
                log('screenshot made');
                log('close browser');
                await browser.close();
                log('browser closed');
                log('loop succeed');

                running--;
            })();
            log('end async');
        }
        log('end loop');

        if (running === 0 && list.length === 0) {
            log('job finished');
        }
    }
}

log('end playwright script');

function log(...msgs) {
    let date = new Date();
    let timeString = date.toISOString().substr(11, 8);
    let msg = '';
    for (let i in msgs) {
        msg += msgs[i];
    }

    console.log(timeString, ':', msg);
}

出力:

20:53:29 : start playwright async
20:53:29 : start job
20:53:29 : runner started
20:53:29 : start browser loop
20:53:29 : fire async
20:53:29 : loop next
20:53:29 : launch: chromium
20:53:29 : end async
20:53:29 : fire async
20:53:29 : loop next
20:53:29 : launch: firefox
20:53:29 : end async
20:53:29 : fire async
20:53:29 : loop next
20:53:29 : launch: webkit
20:53:29 : end async
20:53:29 : end loop
4

4 に答える 4

1

あなたの非同期関数が実際に評価されているとは思いません。

繰り返しごとに async 関数を 1 回呼び出す代わりに、promise のリストを作成してPromise.all()を使用できますか?

于 2020-02-03T21:13:33.553 に答える
1

即時呼び出し関数は、終了を待たずに実行されます。例えば:

const promise = (time = 1, shouldThrowError = false) => new Promise((resolve, reject) => {
  timeInMs = time * 1000
  setTimeout(()=>{
    console.log(`Waited ${time} secs`)
    if (shouldThrowError) reject(new Error('Promise failed'))
    resolve(time)
  }, timeInMs)
});

// Start excuting first async immediate function
(async () => {
  try {
    console.log('starting first promise')
    await promise(1)
    console.log('finished first promise')
  } catch (error) {
    
  }
})();
// This executes without finishing previous promise
(async () => {
  try {
    console.log('starting second promise')
    await promise(1)
    console.log('finished second promise')
  } catch (error) {
    
  }
})();

ブロック コードを変更します。

        (async () => {
            log('loop next');
            ...
            log('loop succeed');

            running--;
        })();

に:

        const process = async () => {
            log('loop next');
            ...
            log('loop succeed');

            running--;
        };
        await process()

また、await を使用できるようにするには、すべてのコードを async 関数でラップする必要があります。

(async () => {
   ...all your code
})();
于 2020-02-03T21:48:00.660 に答える