2014-09-10 116 views
2

我正在考慮使用Dart進行服務器端編程。由於沒有類似於Ruby on Rails的完整框架,因此我正在檢查較低級別的庫。最需要的庫是Posgresql驅動程序。我發現很少和最成熟似乎是https://pub.dartlang.org/packages/postgresqlDart可以同步API嗎?

這是我的問題。 Postgresql驅動程序具有異步API。我知道客戶端需要異步API,只是爲了不阻止UI線程。但是在服務器端線程可用,所以爲什麼Postgresql驅動程序具有異步API?

我對Promises API有所瞭解,但對我來說,這只是在服務器端做事情時不需要的複雜性。代碼可讀性是最重要的。

我只是想知道在Dart語言設計中是否有東西強迫人們構建異步API。所以問題是:Dart是否可以爲數據庫和文件IO操作同步API?

+0

承諾可以是同步的。他們對我來說非常易讀。它們的主要問題是它們可能不太「可調試」,因爲你不能使用標準堆棧展開。例如,使用服務器端代碼,您通常會等待數據庫請求完成,但通過使用異步模式,您可以做一些有用的事情。 – JAre 2014-09-10 18:13:17

回答

1

Dart確實有同步文件操作。例如見File.readAsStringSync()

Dart沒有內置的方式在套接字上執行阻塞IO,這意味着postgresql庫必須是異步的。

Dart即使在服務器上也沒有真正的「線程」。它具有可以並行運行的隔離區,但只能通過消息傳遞進行通信,並且不具有互斥鎖等同步基元。

這是list of server frameworks

在Dart中編寫異步代碼時,Future.then()語法(尤其是多層嵌套)可能會變得單調乏味。幸運的是,async/await功能正在實施中,這意味着您可以編寫異步代碼,但讀取的代碼類似於使用阻止io編寫的代碼。例如:

main() async { 
    var conn = await connect('postgresql://foo'); 
    try {  
    var sql = "select 'foo'"; 
    var result = await conn.query(sql).toList(); 
    return result[0]; 
    } on Exception catch (ex) { 
    print('Query error: $ex'); 
    } finally { 
    conn.close(); 
    } 
} 

由於Nov14的,使用異步等待你需要與--enable_async標誌跑鏢,和崩潰準備,和失蹤的堆棧跟蹤信息 - 此功能正在積極開發並不穩定。另一個更穩定的選擇是使用async_await包來翻譯您的異步/等待代碼以使用期貨。

如果您有關於postgresql驅動程序的任何具體問題(我是作者),請隨時在github上打開一個問題,或給我發一封電子郵件。我的電子郵件地址位於postgresql pub頁面上。

+0

我想要飛鏢。它仍然是「崩潰,缺少堆棧跟蹤信息」的情況嗎? pgsql在等待語法時可以正常工作嗎? – lethalman 2015-11-18 20:57:11

3

Dart庫/包可以提供同步API。數據庫管理員並不傾向於這樣做,因爲您通常不希望阻止整個服務器等待可能長時間的數據庫操作完成。例如,假設你正在創建一個Web服務器,並有一個請求處理程序從數據庫中提取數據並提供服務。如果您只使用同步操作,並且您收到10個請求,則其中9個將在等待第一個請求處理完成之前等待。

如果你只關注可讀性,你可以等待實施的await關鍵字,這將有助於你的代碼感覺像是同步代碼,而實際工作異步:

var conn = await connect(uri); 
var results = await conn.query('select * from users').toList(); 
for(result in results) { 
    print("${result.username} has email address ${result.emailAddress}."); 
} 
+1

'你通常不想阻止整個服務器等待可能長的數據庫操作完成 - 只有當你的服務器非常簡單並且在一個線程中服務所有請求時。我不是Dart程序員,但很顯然你需要在獨立線程中運行每個請求(你有Dart中的期貨和隔離)。 – 2014-09-14 09:46:13

+0

在dart核心庫中,無法阻止套接字io。所以在dart代碼中用同步API編寫數據庫驅動程序是不太可能的。 – 2014-11-17 21:57:13

+0

@OZ_一點也不真實。我建議閱讀關於非阻塞服務器編程。考慮最廣泛部署的網絡服務器nginx使用這種方法。 – 2014-11-17 22:07:20

1

您需要的併發編程服務器,不僅在客戶端。服務器一個接一個地處理來自客戶端的請求會非常低效 - 等到一個請求完全完成後纔開始處理下一個請求,而Dart服務器進程本身正在等待操作系統,數據庫或網絡完成對它的呼叫。

當調用通常是異步的I/O操作時,Dart可以在等待調用的I/O操作完成時開始處理其他請求。

您可以通過使用隔離來改進併發編程,但是您不能創建一個Dart應用程序,該應用程序只執行一些同步調用的I/O調用。

1

Dart不支持多線程,如果不是Dart分離的形式(但那些不是生產就緒)。只有異步處理得到很好的支持,並且在接下來的幾個月裏將向「飛鏢」添加「await」關鍵字(協程的最佳語法)。如果你需要建立一個小型網站,它會很好。 但是,如果您需要針對大型網站或要求苛刻的網絡應用的真正可擴展的解決方案,我建議您使用Dart + Go的組合。讓Dart管理客戶端/ UI端,Golang管理服務器端的數據提供者。由於他創新的「Goroutines」,Go是性能最高的語言服務器端。 Goroutines是一種在多線程中自動運行的表單或協程,它將異步處理的靈活性與同步多線程的效率相結合。 Goroutines會自動複用到多個OS線程中,因此,如果應該阻塞,例如在等待I/O時,其他人將繼續運行。 Go + Dart組合非常強大。

+0

我喜歡Go很多,但是更改爲Dart也是服務器端的,因爲使用相同的語言進行開發會更有效率,尤其是在小型團隊中,沒有人可以專注於客戶端或服務器。 Isolates仍然會遺漏一些功能,但它們很快就會被添加,比起它們已經準備好了(至少在服務器上,很久沒有在瀏覽器中嘗試過了)。 – 2014-09-11 14:36:52

+0

我在哪裏可以找到隔離尚未準備好的「官方聲明」?我知道這聽起來很荒謬,但如果朗準備就緒,那麼裏面的一切都應該做好準備。 – 2014-09-14 10:11:04

相關問題