2016-10-23 35 views
0

如果有人能够帮助解决以下Typescript Error,我将不胜感激。Typescript chaining Promises

谢谢。

我使用以下code它具有以下内容。它需要能够链接Promise

line 26: dbPromise = _db.execute(sql) 

当我尝试构建它,我得到如下:

ERROR in ./app/pages/chats/SqlDatabase.ts 
(26,9): error TS2322: Type 'Promise<SqlResultSet>' is not assignable to type 'Promise<SqlDatabase>'. 
    Type 'SqlResultSet' is not assignable to type 'SqlDatabase'. 
    Property '_db' is missing in type 'SqlResultSet'. 

我使用Typescript version 2.0.3.

代码:

import { isBrowser } from './platform'; 
import { SqlResultSet } from './SqlResultSet'; 

export class SqlDatabase { 

    constructor(private _db: any) { } 

    static open(name: string, initStatements: string[] = []): Promise<SqlDatabase> { 
    let dbPromise = isBrowser() 
     .then(browser => { 
     const openDatabase = browser ? openBrowserDatabase : openCordovaDatabase; 
     return openDatabase(name); 
     }); 
    if (initStatements.length === 0) { 
     return dbPromise; 
    } 
    let _db: SqlDatabase; 
    // execute the first statement and capture the _db 
    dbPromise.then(db => { 
     _db = db; 
     return db.execute(initStatements.shift()); 
    }); 
    // execute all the other statements (if any) sequentially 
    for (let sql of initStatements) { 
     dbPromise.then(() => { 
     dbPromise = _db.execute(sql) 
     }); 
    } 
    // resolve the _db only after all statements have completed 
    return new Promise((resolve, reject) => { 
     console.log('resolve: ', resolve); 
     dbPromise.then(() => resolve(_db)).catch(reject); 
    }); 
    } 

    execute(statement: string, params: any[] = []): Promise<SqlResultSet> { 
    console.log('execute: ' + statement); 
    return new Promise((resolve, reject) => { 
     this._db.transaction(tx => tx.executeSql(statement, params, (tx, resultSet) => { 
     console.log('execute: resolve: ', resultSet); 
     resolve(resultSet); 
     }, (tx, error) => { 
     reject(error) 
     })); 
    }); 
    } 
} 

declare var sqlitePlugin: any; 

function openCordovaDatabase(name: string): Promise<SqlDatabase> { 
    return new Promise((resolve, reject) => { 
    if (typeof sqlitePlugin === 'undefined') { 
     reject(new Error('[ionix-sqlite] sqlitePlugin global object not found; did you install a Cordova SQLite plugin?')); 
    } 
    const db = sqlitePlugin.openDatabase({ 
     name: name, 
     location: 'default' 
    }); 
    console.info('[ionix-sqlite] using Cordova sqlitePlugin'); 
    resolve(new SqlDatabase(db)); 
    }); 
} 

declare function openDatabase(name: string, version: string, desc: string, size: number): any; 

function openBrowserDatabase(name: string): Promise<SqlDatabase> { 
    return new Promise((resolve, reject) => { 
    try { 
     const db = openDatabase(name, '1.0', name, -1); 
     console.info('[ionix-sqlite] using WebSQL'); 
     resolve(new SqlDatabase(db)); 
    } catch (error) { 
     reject(error); 
    } 
    }); 
} 
+0

避免['Promise' constructor antipattern](http://stackoverflow.com/q/23803743/1048572)!只需'返回dbPromise.then(()=> _ db)'。 – Bergi

+0

你确定'isBrowser()'不能同步吗?回复承诺是很多复杂因素的根源,如果可能的话,你应该避免这种复杂性。 –

回答

1

该错误是由于事实上你尝试更改dbPromise的类型。
当它第一次宣称:

let dbPromise = isBrowser() 
     .then(browser => { 
     const openDatabase = browser ? openBrowserDatabase : openCordovaDatabase; 
     return openDatabase(name); 
     }); 

编译器是指类型Promise<SqlDatabase>(基于错误),但你尝试分配别的东西:

dbPromise = _db.execute(sql) 

这是Promise<SqlResultSet>型。
你可以解决它像这样:

let dbPromise: Promise<any> = ... 

或者你可以有两种不同的承诺变量(即:dbPromise: Promise<SqlDatabase>resultPromise: Promise<SqlResultSet>)这听起来更好的给我。

+0

'dbPromise = _db.execute(sql)'无论如何都是完全错误的。如果代码被整理成明智的模式,那行就会消失。 –