我可以使用构造函数内部的第三方库的异步调用填充数组吗?

时间:2018-07-17 18:49:26

标签: javascript

我有一个带有数组属性的对象,我想用从异步调用中收到的响应来填充。调用是通过第三方库中的方法进行的,该方法接收了回调函数,因此我尝试了以下方法:

class Foo {
    constructor() {
        this.myArray = [];

        thirdPartyObject.thirdPartyMethod(
            param1,
            param2,
            function(data){ //success callback
                data.forEach(item => {
                    var myArrayEle = {
                        propertyA : item.propertyA,
                        propertyB : item.propertyB
                    };
                    this.myArray.push(myArrayEle);
                })
            },
            function(data){ //error callback
                throw "Error"
            }
        )
    }
}

我在this.SomeArray.push(myArrayEle);上收到一条错误消息,说“无法读取未定义的属性myArray”。

我不想简单地对响应进行处理,然后放开它,因为我想保留此数组,因此我可以根据用户的操作进行处理,而不必稍后再调用得到相同的数据。

是否可以在构造函数中执行此操作,还是必须在其他地方使用promises?

1 个答案:

答案 0 :(得分:2)

处理此问题的一种方法是在类上具有一个仅用于设置内容的构造函数,以及一个可以处理异步获取数据并让您知道何时正确初始化该对象的不同的init函数。这是我们模拟您的thirdPartyMethod的示例。当您调用构造函数时,该数组将是未定义的,但是您可以调用init().then()来知道何时准备就绪:

const thirdPartyObject = {
  thirdPartyMethod(param1, param2, success, error) {
    setTimeout(() => success([{propertyA: "propA0",propertyB: "propB0"}, {propertyA: "propA1",propertyB: "propB1"
    }]), 1000)
  }
}

class Foo {
  constructor(data) {
    console.log("making instance")
    this.myArray = data;
  }
  init() {
    console.log("starting init")
    return new Promise((resolve, reject) => {
      thirdPartyObject.thirdPartyMethod(
        'param1','param2',
        (data) => { //success callback    // use arrow function so 'this' works 
          this.myArray = data.map(item => {
            return {
              propertyA: item.propertyA,
              propertyB: item.propertyB
            };
          })
          console.log("finished init, data ready")
          resolve(true)
        },
        function(data) { //error callback
          reject("Error")
        }
      )
    })
  }
}

let f = new Foo()
f.init()
  .then(() => console.log(f.myArray))
  .catch(err => console.log(err))