2016-11-21 225 views
2

在我的情況下,我必須獲取customerService上的客戶列表並返回到組件。請任何人都可以通過重寫getCustomersList方法來幫助我。Angular 2承諾不等待解決嵌套承諾?

import { Injectable } from '@angular/core'; 
import { SQLite } from 'ionic-native'; 

@Injectable() 
export class CustomerService { 
    private sDBName:string; 
    private db; 
    private isDBExist:boolean = false; 

    constructor() {} 

    setDBName(sDBName:string) { 
     this.sDBName = sDBName; 
    } 

    connect():Promise<any> {   
     this.db = new SQLite(); 
     return this.db.openDatabase({ 
      name: this.sDBName, 
      location: 'default' 
     }); 
    } 
    getCustomersList():Promise<any> { 
     return Promise.resolve(()=>{    
      return this.connect().then(()=>{     
       this.isDBExist = true; 
       let sql = 'SELECT * FROM customer ORDER BY customer_id DESC LIMIT 10'; 
       return this.db.executeSql(sql, {}).then((result)=>{ 
        let customers = [];    
        for(let i=0; i<result.rows.length; i++) { 
         customers.push(result.rows.item(i)); 
        } 
        return customers; 
       },(err)=>{ 
        this.debug('Unable to select customers', err); 
        return []; 
       }); 
      },(err)=>{ 
       this.debug('Unable to open database', err); 
       return []; 
      }); 
     }); 
    } 
} 

回答

3

你以絕對不自然的方式使用Promise。諾言創建是爲了擺脫所謂的回撥地獄。承諾應該減少異步代碼的複雜性,但是你所做的正是通向回調地獄的道路。

我稍微重寫了你的函數,以便按照Promise標準工作。這可能是一個不工作的現成的解決方案,但你並沒有給我們提供任何plunker,所以這只是一個概念:

getCustomersList(): Promise<any> { 
    return this.connect() 
     .catch(err => throw new Error('Unable to open database', err)) 
     .then(() => { 
      this.isDBExist = true; 
      return this.db.executeSql('SELECT * FROM customer ORDER BY customer_id DESC LIMIT 10', {}) 
     }) 
     .catch('cannot execute query') 
     .then(result => result.rows.map(row => row.item(i))) 
     .catch(err => { 
      this.debug('Unable to select customers', err); 
      return []; 
     }); 
} 

我真的beleive連接到數據庫不應在此進行但是在一些常見的數據庫服務中,這將是您的數據庫層。理想情況下,當你調用這個函數時,數據庫應該已經被連接了/錯誤應該已經被拋出。所以花更多的時間去思考這個架構。

+0

這個回報仍然不會工作,因爲在第一個連接的承諾之內還有一個承諾存在,所以這將不會返回任何我猜。 return語句不會等待內部承諾完成 – Sundar

+1

@Sundar只是更多地瞭解承諾。當'.then'函數返回另一個承諾時,它會等到它解析後再運行下一個'.then' – smnbbrv

1

如果你的方法getCustomersList返回客戶名單,或將查詢客戶列出的功能?如果是前者,那麼這就是要走的路:

getCustomersList(): Promise<any> { 
    return this.connect().then(() => { 
     this.isDBExist = true; 
     let sql = 'SELECT * FROM customer ORDER BY customer_id DESC LIMIT 10'; 
     return this.db.executeSql(sql, {}).then((result) => { 
      let customers = []; 
      for (let i = 0; i < result.rows.length; i++) { 
       customers.push(result.rows.item(i)); 
      } 
      return customers; 
     }, (err) => { 
      this.debug('Unable to select customers', err); 
      return []; 
     }); 
    }, (err) => { 
     this.debug('Unable to open database', err); 
     return []; 
    }) 
}