2016-10-23 36 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)'無論如何都是完全錯誤的。如果代碼被整理成明智的模式,那行就會消失。 –