简体   繁体   中英

Modifying outside variables inside an event handler

I am going through Eloquent JavaScript and I am confused why my solution to one of the exercises does not work. Basically, this script should take a regular expression and one or more paths as arguments, then output an array with paths matching the expression.

'use strict';

async function search(path, re) {
    const {stat, readdir} = require('mz/fs');
    let match = [];
    for (let i of path) {
        let stats = await stat(i);
        if (stats.isDirectory())
            search(await readdir(i), re);
        else if (await matched(i, re)) {
            match.push(i);
        }
    }
    return match;
}

function matched(file, re) {
    const {createReadStream} = require('mz/fs');
    let stream = createReadStream(file);
    let m = false;
    stream.on('data', chunk => {
        if (chunk.toString().match(re)) {
            //console.log('matched');
            m = true;
        }
    });
    return m;
}

let rgx = new RegExp(process.argv[2]);
let paths = process.argv.slice(3);

search(paths, rgx).then(x => console.log(x));

I guess the issue is that m is not modified inside the event handler function; when I add a print statements, they show that the match happens but m is not modified.

I checked the solution online eventually and I have the right idea, but the author is using synchronous functions:

const {statSync, readdirSync, readFileSync} = require("fs");

let searchTerm = new RegExp(process.argv[2]);

for (let arg of process.argv.slice(3)) {
  search(arg);
}

function search(file) {
  let stats = statSync(file);
  if (stats.isDirectory()) {
    for (let f of readdirSync(file)) {
      search(file + "/" + f);
    }
  } else if (searchTerm.test(readFileSync(file, "utf8"))) {
    console.log(file);
  }
}

I really want to get the hang of JavaScript's asynchronous style, so I was hoping someone could help me fix my asynchronous solution.

This return m; will be executed first since stream.on('data'); is async. What you can do is add a callback in function matched(file, re) like function matched(file, re, cb) then use the callback inside stream.on('data'); like cb(chunk.toString().match(re));

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