Q:

unable to set proper scope for variable within a JavaScript promise

I've come across a weird issue where a new variable is being created in local scope even if it is defined outside,
from the below code
after I call buildMeta() and check the contents of "data", it is always empty 
implying that it's not being modified at all, even if I've specifically targeted "that.data" where that refers to the class' object.
I'd appreciate if anyone would point out what I am doing wrong.
class meta {

    constructor(files) {
        if(!files) throw Error("files not specified");
        this.data = {};
        this.ls = files;
    }

  buildMeta() {
        var that = this;
        for(let i = 0; i < that.ls.length; i++) {

            mm.parseFile(that.ls[i]).then(x => {
                var info = x.common;
                that.data[info.artist] = "test";
            }).catch((x) => { 
               console.log(x);    
            });
       }

    }
 }
const mm = new meta(indexer); // indexer is an array of file paths
mm.buildMeta();
console.log(mm.data);

A:

You are logging mm.data before parseFile has finished. Your code implies that it returns a promise, so your insertion into that.data will happen after your console.log(mm.data) executes.
You need to return a promise from buildMeta, so that you can do...
const mm = new meta(indexer);
mm.buildMeta().then(() => {
    console.log(mm.data);
})

Here's a buildMeta that should do what you need. This returns a promise that waits for all of the parseFile invocations to do their work and update this.data...
buildMeta() {
    return Promise.all(this.ls.map(f => mm.parseFile(f).then(x => {
        var info = x.common;
        this.data[info.artist] = "test";
    })))
}

