Warm tip: This article is reproduced from serverfault.com, please click

javascript-异步功能在确实还有更多工作要做时才识别出功能已完成

(javascript - Asynchronous function recognizes function is done when really it still has more to do)

发布于 2020-12-04 04:36:12

page.on由异步for循环底部的完成,并准备再次运行功能reconized,但它实际上没有完成。它仍然需要运行一切page.close如何让异步函数知道它是在page.close之后而不是在page.on之后完成的?让我知道是否需要更多信息,谢谢。

const puppeteer = require('puppeteer');
const fs = require('fs');
const req = require('request');
const got = require('got');
const NodeID3 = require('node-id3');
const readline = require('readline');
const selectors = require('./selectors');

const getDownloadUrl = async (url, browser) => {
    const page = await browser.newPage();
    await page.goto(url);
    page.setRequestInterception(true);
    await page._client.send('Page.setDownloadBehavior', {behavior: 'allow', downloadPath: './Songs'})

    const baseUrl = 'https://cf-hls-media.sndcdn.com/media/';

    await page.on('request', async (request) => {
        if(request.url().includes(baseUrl)){
            const downloadUrl = fixUrl(request.url());
            const info = await getSongInfo(page);
            downloadSong(downloadUrl, info.title);
            await tagSong(info);
            await request.abort();
            await page.close();
        } else {
            request.continue();
        }
    });
};

const fixUrl = (url) => {
   ...
};

const downloadSong = (url, title) => {
   ...
};

const getSongInfo = async (page) => {
   ...
};

const tagSong = async (info) => {
   ...
};

(() => {
    const readInterface = readline.createInterface({
        input: fs.createReadStream('../Song Urls.csv'),
        output: process.stdout,
        console: false,
        terminal: false,
    });
    
    let urls = [];
    readInterface.on('line', function(line) {
        urls.push(line);
    }).on('close', async () => {
        const browser = await puppeteer.launch({headless: false});

        for (let i = 0; i < urls.length; i++) {
            const url = urls[i];
            await getDownloadUrl(url, browser);
        }
    });
})();

/*
Issue: The loop recognizes that the getDownloadUrl function is done even though it's
not and continues anyways.
*/
Questioner
ethans33
Viewed
0
Nicholas Tower 2020-12-04 13:07:59

await仅与promise一起使用,并且page.on看起来是基于回调的事件侦听器,而不是返回promise的东西。如果你希望能够等待它,则需要围绕它创建一个承诺。

await new Promise((resolve) => {
  page.on('request', async (request) => {
    if(request.url().includes(baseUrl)){
      const downloadUrl = fixUrl(request.url());
      const info = await getSongInfo(page);
      downloadSong(downloadUrl, info.title);
      await tagSong(info);
      await request.abort();
      await page.close();
      resolve();
    } else {
      request.continue();
    }
  });
})