在Promise +数组中未定义'this'。降低()

时间:2017-10-08 16:51:37

标签: javascript arrays promise this reduce

今天早上我遇到了一个问题。

我有什么

基本上,我有一个简单的类,有一个要注册的文件数组:

function MyClass() {

    this.filesToRegister = [
        {
            "fileName": "http://tny.im/azk"
        },
        {
            "fileName": "http://tny.im/azk"
        }
    ];
}

我还有一个简单的函数_contextFunction(),它只需要一个fileToRegister条目:

MyClass.prototype._contextFunction = function(fileToRegister) {

    return new Promise((resolve, reject) => {

        logger.info(typeof this.filesToRegister);
        logger.info('current file: ' + fileToRegister);
        return resolve();
    });
};

请注意,此函数必须访问上下文(this),这是必需的,我无法更改。

最后,我有一个实用程序方法processArray(),它可以对数组的每个项应用一个函数,所有这些都是同步完成的:

MyClass.prototype.processArray = function(array, fn) {

    let results = [];
    return array.reduce((p, item) => {

        return p.then(() => {

            return fn(item).then((data) => {

                results.push(data);
                return results;
            }).catch(err => console.log(err));
        });
    }, Promise.resolve());
};

我想做什么

我使用此实用程序方法在_contextFunction()数组的每个项目上应用filesToRegister

this.processArray(this.filesToRegister, this._contextFunction);

它没有问题,并在this._contextFunction()的每个项目上执行this.filesToRegister

问题是什么

但是,当我尝试在typeof this.filesToRegister中记录_contextFunction()时,结果为undefined ...经过多次测试后,我得出结论,上下文中没有任何内容可访问(两者都没有上下文属性也没有上下文方法)。

但是,如果我在没有this._contextFunction()方法的情况下执行processArray(),我可以访问上下文(上下文属性和上下文方法)。

我在想什么

我的猜测是问题来自processArray()方法,但我看不到...我试图在typeof this.filesToRegister方法中记录processArray(),并且工作...

总结:

  • processArray()能够访问上下文。
  • this._contextFunction()推出'独立'即可访问上下文。
  • this._contextFunction()发起的
  • processArray()无法访问上下文。

任何人都可以帮助我吗?感谢

1 个答案:

答案 0 :(得分:2)

fn(item)

在没有上下文的情况下调用函数。使用:

fn.call(this, item)

或者传递方法名称:

this.processArray(this.filesToRegister,"_contextFunction");

然后做:

this[fn](item);

我将如何做到这一点:

class MyClass {
 constructor(){
   this.files = [];
 }
 async add(file){
   await "whatever";
   this.files.push(file);
 }
 multiple(name, array){
   return Promise.all( array.map(el => this[name](el)));
 }
}

然后:

const instance = new MyClass;
instance.add("whatever");
instance.multiple("add",[1,2,3]);