2013-04-26 42 views
3

我已阅读了大量有关此(异步和期货)的帖子和文章,并且我不确定当前情况如何。我尝试了许多不同的变化。如何按顺序处理异步代码

我试图在序列下面的代码的过程:

import 'dart:async' as async; 
import 'dart:io'; 
import 'dart:math'; 
import 'package:postgresql/postgresql.dart' as pg; 

var uri = 'postgres://admin:[email protected]:5432/testdb'; 
List lgNames = ['Peter', 'Robert', 'Mary', 'Marg', 'William', 
      'Vern', 'Dermot', 'Monty', 'Peggy', 'Sue', 'William']; 

List lgUsed = []; 

Random rand1 = new Random(); 

void main() { 
    pg.connect(uri).then((oDb) { 
    print ("Connected to database"); 

    fClearTable(oDb).then((String sResult){ 
     print(sResult);  

     for (int iPos = 0; iPos < 3; iPos++) { 
     fListTable(oDb, "Select before Insert number ${iPos+1}").then((String sResult) => 
      print(sResult)); 

     fInsertData(oDb, "Insert Number ${iPos+1}").then((String sResult) => 
      print(sResult));   

     fListTable(oDb, "Select after Insert number ${iPos+1}").then((String sResult) => 
      print(sResult)); 
     } 
    }); 
    }); 
} 

async.Future<String> fClearTable(oDb) { 
    async.Completer oCompleter = new async.Completer(); 
    oDb.execute("DELETE FROM test01").then((oResult){ 
    oCompleter.complete("Table has been cleared"); 
    }); 
    return oCompleter.future; 
} 

async.Future<List> fListTable(oDb, sMsg) { 
    async.Completer oCompleter = new async.Completer(); 
    oDb.query("SELECT * FROM test01").toList().then((lResult){ 
    String sResult = "$sMsg = $lResult"; 
    oCompleter.complete(sResult); 
    }); 
    return oCompleter.future; 
} 

async.Future<String> fInsertData(oDb, sMsg) { 
    async.Completer oCompleter = new async.Completer(); 
    oDb.execute("Start Transaction").then((oResult){ 
    String sName; 
    for (bool tFound = true; tFound;) { 
     int iPos = rand1.nextInt(10); 
     sName = lgNames[iPos]; 
     tFound = false; // init 
     for (iPos = 0; iPos < lgUsed.length && !tFound; iPos++){ 
     tFound = (sName == lgUsed[iPos]); 
     } 
    } 
    lgUsed.add(sName); 
    String sSql = """INSERT INTO test01 (name) 
     VALUES ('$sName')"""; 
    print("$sSql"); 
    oDb.execute(sSql).then((oVal){ 
     oDb.execute("COMMIT").then((oVal){ 
     oCompleter.complete(sMsg); 
     }); 
    }); 
    }); 
    return oCompleter.future; 
} 

该计划的目的是循环三次: a)选择表 B)插入一行到表中。 c)选择表

程序的输出结果清楚地显示了所有三个插入。

从程序的输出如下:显示

Connected to database 
Table has been cleared 
Select before Insert number 1 = [] 
INSERT INTO test01 (name) 
    VALUES ('Vern') 
Select after Insert number 1 = [] 
Select before Insert number 2 = [] 
INSERT INTO test01 (name) 
    VALUES ('Peter') 
Select after Insert number 2 = [] 
Select before Insert number 3 = [] 
INSERT INTO test01 (name) 
    VALUES ('Robert') 
Select after Insert number 3 = [] 
Insert Number 1 
Insert Number 2 
Insert Number 3 

A选择在节目结束的psql:

testdb=# select * from test01; 
id | name 
-----+-------- 
157 | Vern 
158 | Peter 
159 | Robert 
(3 rows) 

有没有办法达到我想要的IE浏览器。对于插入后的选择显示表中的新值?

欢迎任何相关的意见。

回答

4

要开始,here's关于期货如何在飞镖工作的伟大文章。

你真的需要知道的是,Futures里面的代码在所有同步代码完成后运行。此外,根据定义,期货是异步完成的,所以期待一个期货在另一个期货之前完成是不合理的,除非它们被链接在一起。

也就是说:

main() { 
    print('first'); 
    someFutureCall().then((_) => print('second?')); 
    someOtherFutureCall().then((_) => print('third?')); 
    print('last?'); 
} 

这将打印: '持续' 第一',然后然后两个期货可以以任何顺序完成。你不能分辨哪个会先完成。你所知道的是,同步代码首先发生。

有正确的顺序,这样做:

main() { 
    print('first'); 
    someFutureCall() 
    .then((_) => print('second?')) 
    .then((_) => someOtherFutureCall()) 
    .then((_) => print('third?')) 
    .then((_) => print('last?')); 
} 

所以你的样品的方式,顺序不保留用将来时。你想要的是:

void main() { 
    pg.connect(uri).then((oDb) { 
    print ("Connected to database"); 
    return fClearTable(oDb); 
    }).then((String sResult){ 
    print(sResult);  
    return Future.forEach([0, 1, 2], (i) { 
     return fListTable(oDb, "Select before Insert number ${iPos+1}") 
     .then((String sResult) => print(sResult)) 
     .then((_) => fInsertData(oDb, "Insert Number ${iPos+1}")) 
     .then((String sResult) => print(sResult)) 
     .then((_) => fListTable(oDb, "Select after Insert number ${iPos+1}")) 
     .then((String sResult) => print(sResult)); 
    }); 
    }); 
} 

另请参阅API documentation for Futures