Javascript 异步等待逻辑返回问题

Javascript 异步等待逻辑返回问题,javascript,node.js,async-await,Javascript,Node.js,Async Await,因此,我有一些问题,试图找出如何修复下面的剪报。到目前为止,它在for of循环的'request(scanurl,…'部分运行之前返回值。循环确实运行。此外,我不认为'lines200'变量正在通过计数器更新。我是一名学习者,因此任何解释都将不胜感激 async function processLineByLine(baseData) { console.log('enter async func') try { const fileStream = fs.createReadSt

因此,我有一些问题,试图找出如何修复下面的剪报。到目前为止,它在for of循环的'request(scanurl,…'部分运行之前返回值。循环确实运行。此外,我不认为'lines200'变量正在通过计数器更新。我是一名学习者,因此任何解释都将不胜感激

async function processLineByLine(baseData) {
    console.log('enter async func')
try {
  const fileStream = fs.createReadStream('./file.txt');
  let linesTotal = 0;
  let lines200 = 0;

  const rl = readline.createInterface({
    input: fileStream
  });
  for await (let line of rl) {
    console.log('in loop')
    const scanurl = (baseData.match(/http/gi)) ? (baseData) : ('https://' + baseData + line);
    linesTotal++;

  request(scanurl, {json: true}, function (error, response, body) {
            let statusCode = response.statusCode;
            let htmlBody = body;
            //console.log(htmlBody)
            //console.log(statusCode)
            if (statusCode == "200") {
                console.log('in 2nd if')
                let $ = cheerio.load(htmlBody);
                let titleScrape = $('title').html();
                console.log(titleScrape)
                if (titleScrape.match(/404 | test/gi)) { 
                    console.log('Matched')
                } else {
                        lines200++;
                        console.log(lines200)
                    }
                } else {
                    // Do nothing
                }
            });

        }
        return {
            total: linesTotal,
            count200: lines200,
        }; 
} catch (error) {
    console.error(error)
}

}

router.get('/:reqTarget', async (req, res) => {
    console.log('starting')
    var baseUrl = req.params.reqTarget;
    try {
        console.log('in the try')
    const initTest = await processLineByLine(baseUrl);
    const {total, count200} = initTest;
    console.log(total, count200)
    if (initTest) return res.status(200).send({
        message: 'STATUS 200 COUNT: ' + count200 + ' ' + 'TOTAL: ' + total });

    } catch (error) {
        console.log(error)
    }

});
电流输出:

starting
in the try
enter async func
in loop
in loop
in loop
in loop
in loop
in loop
in loop
33 0 //this is the return that is two early
in 2nd if
404 | test
Matched
in 2nd if
404 | test
Matched

当你有一个包含异步操作的循环时,你有两个选项中的一个。你可以并行运行它们,并以某种方式跟踪它们的完成时间。或者,你可以一个接一个地顺序运行它们。看起来你的循环可以以任何一种方式构造,但我将演示顺序选项

<>代码< Acthc/AsAs/<代码>的出现,允许我们在适当的<代码> > <代码>中间暂停“<代码> < /COD>循环”。但是,为了做到这一点,所有异步操作都必须是基于承诺的,因此您可以“<代码>等待< /CODE >这些承诺。为此,我已经从<代码>请求()切换。library到
request-promise-native
库,该库是
request
库的承诺包装器,使用本机内置承诺。它还有另一个很好的功能,可以自动检查2xx状态代码,因此您无需自己进行检查

下面是该代码的外观:

const rp = require('request-promise-native');

async function processLineByLine(baseData) {
    console.log('enter async func')
    try {
        const fileStream = fs.createReadStream('./file.txt');
        let linesTotal = 0;
        let lines200 = 0;

        const rl = readline.createInterface({
            input: fileStream
        });
        for await (let line of rl) {
            console.log('in loop')
            const scanurl = (baseData.match(/http/gi)) ? (baseData) : ('https://' + baseData + line);
            linesTotal++;

            try {
                let htmlBody = await rp(scanurl, {json: true});
                let $ = cheerio.load(htmlBody);
                let titleScrape = $('title').html();
                console.log(titleScrape);
                if (titleScrape.match(/404 | test/gi)) {
                    console.log('Matched')
                } else {
                    lines200++;
                    console.log(lines200)
                }
            } catch(e) {
                console.log(`error on request(${scanurl})`, e);
                // like your original code, this will only log the error
                //   and then continue with the rest of the URLs
            }
        }
        return {
            total: linesTotal,
            count200: lines200,
        };
    } catch (error) {
        console.error(error)
    }

}

router.get('/:reqTarget', async (req, res) => {
    console.log('starting')
    var baseUrl = req.params.reqTarget;
    try {
        console.log('in the try')
        const initTest = await processLineByLine(baseUrl);
        const {total, count200} = initTest;
        console.log(total, count200)
        res.status(200).send({message: 'STATUS 200 COUNT: ' + count200 + ' ' + 'TOTAL: ' + total});

    } catch (error) {
        console.log(error)
        res.sendStatus(500);
    }

});

request(scanurl,{json:true},函数(错误、响应、正文){
是异步的……你不需要等待它开始,更不用说完成了……
await
并没有神奇地等待异步代码完成,它在等待一个承诺——而你没有承诺被请求者返回。现在有一个版本的问题每天被问10次。也许这是重复,但现在比以前更疯狂这过去是因为人们现在显然认为
async
await
具有神奇的能力,可以知道何时完成了基于回调的异步操作(提示它们不-
async
函数仅在与异步操作的完成相关的承诺下使用
await
时才有帮助).代替等待,可以使用setTimeoutfunction@LDS那是个糟糕的建议