Javascript承诺反模式错误

时间:2016-10-17 06:41:56

标签: javascript sqlite promise

我正在使用Ionic 2和SQLite。我收到错误,我怀疑这是因为我没有正确使用Promise。

我收到以下错误:

  

错误的刷新秘密:{}

     

TypeError {stack:(...),message:"无法读取属性' executeSql'   未定义"}

TS

private database = new SQLite();

public openDatabase(): Promise<Array<Message>> {
    let promise: Promise<Array<Message>> = new Promise<Array<Message>>(resolve => {
        if (this.database) {
            let promiseChats: Promise<any> = this.refreshChats();
            let promiseMessages: Promise<any> = this.refreshMessages();
            Promise.all([promiseChats, promiseMessages]).then(() => { resolve(this.messages) });
        } else {
            this.database.openDatabase({
                name: "data.db",
                location: "default"
            }).then(() => {
                let promiseChats: Promise<any> = this.refreshChats();
                let promiseMessages: Promise<any> = this.refreshMessages();
                Promise.all([promiseChats, promiseMessages]).then(() => { resolve(this.messages) });
            }, (error) => {
                console.log("OPEN ERROR: ", error);
            });
        }
    });
    return promise;
}

public refreshChats(): Promise<any> {
    return this.database.executeSql("SELECT * FROM chats", [])
        .then((chatData) => {
            this.chats = [];
            if (chatData.rows.length > 0) {
                for (var i = 0; i < chatData.rows.length; i++) {
                    this.populateChat(chatData, i);
                }
            }
            return this.chats;
        })
        .catch(error => {
            console.log("ERROR REFRESHING CHATS: " + JSON.stringify(error));
            console.log(error);
        });
}

当我调试代码并在this.database.executeSql上中断时,this.database不是undefined。此外,您还可以看到this.database上有一个检查,看看它是否undefined。然而,调试器会将Promise移出error,报告显示的错误。

此外,在Promise完成后,会填充this.chats。所以我很困惑。

如果有人能够提出我的错误建议,我将不胜感激。

更新

我已按如下方式更新了代码,但仍然遇到同样的错误:

public openDatabase(): Promise<Array<Message>> {
    let promise: Promise<Array<Message>> = new Promise<Array<Message>>(resolve => {
        if (this.database) {
            Promise.all([this.refreshChats(), this.refreshMessages()]).then(() => { resolve(this.messages) });
        } else {
            this.database.openDatabase({
                name: "data.db",
                location: "default"
            }).then(() => {
                Promise.all([this.refreshChats(), this.refreshMessages()]).then(() => { resolve(this.messages) });
            }, (error) => {
                console.log("OPEN ERROR: ", error);
            });
        }
    });
    return promise;
}

public refreshChats(): Promise<any> {
    return this.database.executeSql("SELECT * FROM chats", [])
        .then((chatData) => {
            let promises: Array<any> = [];
            this.chats = [];
            if (chatData.rows.length > 0) {
                for (var i = 0; i < chatData.rows.length; i++) {
                    promises.push(this.populateChat(chatData.rows.item(i)));
                }
            }
            Promise.all(promises).then(() => {
                return this.chats;
            });
        })
        .catch(error => {
            console.log("ERROR REFRESHING CHATS: " + JSON.stringify(error));
            console.log(error);
        });
}

1 个答案:

答案 0 :(得分:0)

你正在使用一些Promise反模式,我将向你描述。虽然我看不出它会导致您的问题的原因,但它可能有助于调试。

它被称为explicit-construction anti-pattern,基本上是在您不必要地创建new Promise时。

例如,在你的代码中,你的两个函数在开始时创建一个新的Promise,它们可以只返回稍后使用的promise;

public refreshChats(): Promise<Array<Chat>> {
  if (!this.database || this.database === null) {
    console.log('ERROR refreshing chats: database = ' + this.database);
  }

  return this.database.executeSql("SELECT * FROM chats", [])
    .then((chatData) => {
      this.chats = [];
      if (chatData.rows.length > 0) {
        for (var i = 0; i < chatData.rows.length; i++) {
           this.populateChat(chatData, i);
        }
      }
      return this.chats;
    })
    .catch(error => {
      console.log("ERROR REFRESHING CHATS: " + JSON.stringify(error));
      console.log(error);
    });
} 

这可能有助于解决您的错误,以便您可以看到它的来源。如果您提供任何进一步的信息,请ping我,我会更新我的答案。