首页 文章

打字稿异步函数包装承诺

提问于
浏览
0

我正在使用 Typescriptionic 以及javascript上的 async-await 新手 . 我想知道如何包装调用多个promise以返回promise的方法 . 我会尝试更好地阐述:

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

Then ,当promise解析并返回DB对象时,我需要使用它来执行事务中的某些语句来创建所有表,并在我调用事务中所有语句的执行时返回新的promise .

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

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

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


CODE
以下是我目前的 Typescript 代码 . 它's not valid typescript as I don'知道如何从 async 函数返回 Promise<SQLiteObject> .

async createDatabase(): Promise<SQLiteObject> {

        this.sqlite.create({
            name: this.dbName,
            location: this.dbLocation
        }).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)`;

            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;
                })
                .catch(error => {
                    console.log(`Error creating tables - ${error}`);
                });
        }).catch(
            error => console.log(`Error at SQLite initialization - ${error}`)
        );
    }

RESEARCH SO FAR

2 回答

  • 2

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

    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() 处理程序:当您获得另一个promise时,只需从第一个处理程序返回它,并在另一个链接另一个 .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}`));
    
  • 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

    希望能帮助到你! :)

相关问题