打字稿异步函数包装承诺

时间:2017-06-28 11:34:26

标签: javascript typescript asynchronous ionic-framework async-await

我正在使用Typescriptionic以及javascript上的async-await新手。我试图获得一个很好的承诺,但我无法弄清楚如何包装调用多个promises返回promise的方法。我会尝试更好地阐述:

基本上,我有一个可以创建SQLite数据库的对象,当调用create()方法时,它会返回一个Promise一个实际的数据库对象。创建

然后,当promise解析并返回DB对象时,我需要使用它来执行事务中的一些语句来创建所有表,并在我调用时返回一个新的promise执行交易中的所有陈述。

然后当事务完成并且一切顺利时,我需要将数据库对象分配给类属性并设置一个标志,指示数据库已创建并准备就绪。

所以我认为将这个数据库初始化的东西包装在一个名为createDatabase()的方法或类似的东西中是一个好主意,它返回一个Promise<SQLiteObject>,其中SQLiteObject表示数据库。这个方法将在初始化时调用,并且一旦一切正常就应该返回表示数据库的SQLiteObject,或者抛出一个我将登录.catch()的{​​{1}}方法的错误。

我对promises以及如何使用Promisethen()方法有基本的了解,但是当我必须创建数据库时,我有点困惑,然后在promise解析时执行其他操作,当一切都完成后,返回一个包含DB对象的catch(),该对象是类Promise的一个实例。

CODE
以下是我当前的SQLiteObject代码。它不是有效的打字稿,因为我不知道如何从Typescript函数返回Promise<SQLiteObject>

async

研究SO FAR

2 个答案:

答案 0 :(得分:2)

您使用了async,这意味着您可以在await任何时候在函数内部使用Promise,并将代码编写为几乎同步。

async createDatabase(): Promise<SQLiteObject> {
    let db: SQLiteObject;
    try {
      db = await this.sqlite.create({
        name: this.dbName,
        location: this.dbLocation
      });
    } catch(error) {
        console.log(`Error at SQLite initialization - ${error}`);
        return;
    );
    // Insert all tables.
    let createTableParam: string = `CREATE TABLE IF NOT EXISTS param (name PRIMARY KEY NOT NULL, value TEXT)`;
    let createTableNews: string = `CREATE TABLE IF NOT EXISTS news (id PRIMARY KEY NOT NULL,title TEXT,
        content TEXT, image TEXT, date DATE)`;

     try {
       await db.transaction(tx => {
                tx.executeSql(createTableParam);
                tx.executeSql(createTableNews);
                // Add here more tables to create if needed
            }
          );

       console.log('Tables were created');
       this.isActive = true;
       return db;
     catch(error) {
         console.log(`Error creating tables - ${error}`);
     });
}

如果没有await,您需要确保返回初始承诺。

return this.sqlite.create({...

然后再往下走,你可以返回db对象:

       this.isActive = true;
       return db;

此外,您应该避免嵌套.then()处理程序:当您获得另一个承诺时,只需从第一个处理程序返回它,并在结尾链接另一个.then

createDatabase(): Promise<SQLiteObject> {
    let database: SQLiteObject = null;
    return this.sqlite.create({
        name: this.dbName,
        location: this.dbLocation
    })
    .catch(error => console.log(`Error at SQLite initialization - ${error}`))
    .then( (db: SQLiteObject) => {
        // Insert all tables.
        let createTableParam: string = `CREATE TABLE IF NOT EXISTS param (name PRIMARY KEY NOT NULL, value TEXT)`;
        let createTableNews: string = `CREATE TABLE IF NOT EXISTS news (id PRIMARY KEY NOT NULL,title TEXT,
            content TEXT, image TEXT, date DATE)`;
        database = db;
        return db.transaction(tx => {
                tx.executeSql(createTableParam);
                tx.executeSql(createTableNews);
                // Add here more tables to create if needed
            }
        );
    })
    .then( () => {
        console.log('Tables were created');
        this.isActive = true;
        return database;
    })
    .catch(error => console.log(`Error creating tables - ${error}`));

答案 1 :(得分:2)

看来你没有解决这个承诺。

必须解析或拒绝承诺,以便异步函数能够使用值进行响应。

来自TypeScript Deep Dive:

const promise = new Promise((resolve, reject) => {
    resolve(123);
});
promise.then((res) => {
    console.log('I get called:', res === 123); // I get called: true
});
promise.catch((err) => {
    // This is never called
});

所以在我看来你应该创建一个承诺,当创建数据库并且一切都解决它时,如果数据库创建有问题,请拒绝它。

请记住,您可以链接承诺,因此您可以在创建数据库时链接它们。

来自TypeScript Deep Dive:

  

承诺的连锁能力是承诺提供的利益的核心。一旦你有了承诺,从那时起,你就可以使用then函数创建一个承诺链。

查看此URL以获取有关承诺的更多信息

希望它有所帮助! :)