2016-06-08 36 views
2

是否可以阻止返回未來的函數調用?製作Future塊直到完成

我的印象是.then()這樣做,但這並不是我在輸出中看到的。

print("1"); 
HttpRequest.getString(url).then((json) { 
    print("2"); 
}); 
print("3"); 

我所看到的在我的輸出是:

1 
3 
2 

getString方法不具有async,讓我來awaitthen在任何情況下異步執行。

static Future<String> getString(String url, 
     {bool withCredentials, void onProgress(ProgressEvent e)}) { 
    return request(url, withCredentials: withCredentials, 
     onProgress: onProgress).then((HttpRequest xhr) => xhr.responseText); 
    } 

我如何阻止它沒有把無限的,而之前的步驟3等待第2步循環完成(而不是它會反正工作,由於飛鏢的單線程性質)?上面的HttpRequest

的加載config.json文件決定一切的應用程序是如何工作的,如果在配置爲字段請求完成config.json文件之前加載完成後,它會導致錯誤,所以我需要等到文件在我允許在類的字段上調用getter之前完成加載,或者getters需要等待config.json文件的一次加載。

更新,這是我最終沒有使它工作岡特建議後,我用一個Completer

@Injectable() 
class ConfigService { 

    Completer _api = new Completer(); 
    Completer _version = new Completer(); 

    ConfigService() { 

     String jsonURI = 
      "json/config-" + Uri.base.host.replaceAll("\.", "-") + ".json"; 
     HttpRequest.getString(jsonURI).then((json) { 

      var config = JSON.decode(json); 
      this._api.complete(config["api"]); 
      this._version.complete(config["version"]); 

     }); 
    } 

    Future<String> get api { 
     return this._api.future; 
    } 

    Future<String> get version { 
     return this._version.future; 
    } 

} 

而且在那裏我使用ConfigService

@override 
ngAfterContentInit() async { 

    var api = await config.api; 
    var version = await config.version; 

    print(api); 
    print(version); 

} 

現在,我得到阻塞式的功能,而不會實際阻塞。

回答

2

有沒有辦法阻止執行,直到異步代碼完成。你可以做的是連續代碼,以便它在異步代碼完成之前不會被執行。到鏈

的一種方式是then

print("1"); 
HttpRequest.getString(url) // async call that returns a `Future` 
.then((json) { // uses the `Future` to chain `(json) { print("2"); }` 
    print("2"); 
}); 
print("3"); // not chained and therefore executed before the `Future` of `getString()` completes. 

一個異步呼叫剛剛調度代碼以供稍後執行。它將被添加到事件隊列中,並且在處理它之前的任務時,它自己將被執行。在安排異步調用之後,同步代碼print(「3」)繼續。

在你的情況下,HttpRequest.getString()安排一個呼叫到你的服務器,並註冊(json) { print("2")作爲回調,當來自服務器的響應到達時被調用。應用程序的進一步執行在響應到達之前不會停止,並且沒有辦法做到這一點。相反的是,同步代碼將繼續執行(print("3"))。 如果您當前執行的同步代碼達到其結尾,則下一個計劃任務將以相同方式處理。

then()安排在getString()完成後執行的代碼(json) { print("2"); }

等待

asyncawait只是使異步代碼看起來更像同步代碼,但否則是很相同,引擎蓋下將被轉換爲xxx.then((y) { ... })

+0

嗯,相當泡菜!在被加載的那個json文件中,有一個我需要加載到ConfigService中的URL。 NG2的加載速度非常快,當它開始向該URL發送RPC調用數據時,config.json文件仍然被加載,從而導致404錯誤。 –

3

我不知道我知道你想達到什麼樣的,但在我看來,你想這樣做:只需要在消費函數

myFunction() async { 
    print("1"); 
    final json = await HttpRequest.getString(url); 
    print("2"); 
    print("3"); 
} 
2

async聲明。換句話說,生產者功能不需要有async,他們只需要返回Future

你應該能夠做到這一點:

Future consumerFunc() async { 
    print("1"); 

    var response = await HttpRequest.getString(url); 

    print("2"); 

    print("3"); 
} 

,並應導致:

1 
2 
3 

注:await取代then方法