部分代碼的單獨(dú)工作流程
異步編程是一種原則,允許您的程序的一部分在等待應(yīng)用程序線程中發(fā)生的其他活動(dòng)時(shí)運(yùn)行疲陕。它允許您的部分代碼獨(dú)立于主工作流程運(yùn)行禽最。
異步過(guò)程的幾個(gè)例子是:從網(wǎng)絡(luò)獲取數(shù)據(jù)泉坐,或循環(huán)一些非常大的數(shù)據(jù)塊。
在Flutter中有一系列編寫(xiě)異步代碼的方法净宵。一些流行的方法是:
- Future
- Async/Await
- Streams
這篇文章的目的是讓你開(kāi)始在你的flutter應(yīng)用程序中使用流,我希望你有關(guān)于編寫(xiě)flutter應(yīng)用程序的先驗(yàn)知識(shí)裹纳,讓我們開(kāi)始吧择葡!
什么是反應(yīng)式編程?
根據(jù)維基百科:
反應(yīng)式編程是一種圍繞數(shù)據(jù)流和變化傳播的編程范例剃氧。這意味著應(yīng)該可以在所使用的編程語(yǔ)言中輕松表達(dá)靜態(tài)或動(dòng)態(tài)數(shù)據(jù)流敏储,并且底層執(zhí)行模型將自動(dòng)通過(guò)數(shù)據(jù)流傳播更改。
在反應(yīng)式編程中朋鞍,數(shù)據(jù)在由您使用的語(yǔ)言已添,框架或庫(kù)設(shè)置的結(jié)構(gòu)中流動(dòng)妥箕,使得當(dāng)數(shù)據(jù)在一端傳遞到結(jié)構(gòu)中時(shí),如果該數(shù)據(jù)的值發(fā)生更改更舞,則輸出將始終自行更新畦幢。
這正是Steams所做的。流是異步事件流缆蝉,將其視為包含液體的管道宇葱。你從管道的一端倒出液體,它從另一端出來(lái)刊头。
流可以攜帶和處理不同類(lèi)型的數(shù)據(jù)黍瞧,如對(duì)象,函數(shù)芽偏,映射雷逆,列表,甚至流的流污尉。太酷了呃膀哲?
代碼示例
第一個(gè)示例創(chuàng)建一個(gè)簡(jiǎn)單的流,它接收一個(gè)字符串并在完成后將其打印出來(lái):
@override
void initState() {
super.initState();
Stream<String> stream = new Stream.fromFuture(inputData());
stream.listen((data) {
print("Our data: " + data);
}, onDone: () {
print("Done");
}, onError: (error) {
print("Error returned");
});
}
Future<String> inputData() async {
print("Fetching Data...");
return "Let's Use Streams!";
}
輸出
Fetching Data…
Our Data: Let’s use Streams!
Done
這里被碗,Stream從inputData()
返回文本的函數(shù)中獲取數(shù)據(jù)“Let’s use streams!”
某宪。然后,我們用stream.listen()
對(duì)輸入流中的數(shù)據(jù)锐朴。在這里兴喂,我們有一個(gè),和方法焚志。在進(jìn)程完成時(shí)使用數(shù)據(jù)衣迷,如果有的話可以用來(lái)拋出錯(cuò)誤。onDone()``onError()``onDone()``onError()
第二個(gè)例子
final StreamController controller= StreamController();
controller.stream.listen((data) {
print("received data: $data");
}, onDone: () {
print("Stream done");
}, onError: () {
print("Error occured");
});
// data flowing into the stream
controller.sink.add('stream controllers are awesome');
controller.sink.add("Because You can do more");
controller.sink.add('random string');
// Close the StreamController when done to avoid memory leaks
controller.close();
輸出
received data: stream controllers are awesome
received data: Because you can do more
received data: random string
Stream done
所述StreamController
類(lèi)創(chuàng)建為創(chuàng)建的任何流的控制器酱酬。讓您更容易使用多個(gè)監(jiān)聽(tīng)(我們很快就會(huì)開(kāi)始)壶谒。這里我們使用添加數(shù)據(jù)[sink](https://api.flutter.dev/flutter/dart-async/StreamSink-class.html).add()
,這是一個(gè)接受輸入到流中的數(shù)據(jù)的對(duì)象膳沽。此外汗菜,您應(yīng)該在使用后關(guān)閉控制器,以防止內(nèi)存泄漏挑社。
廣播流
這種類(lèi)型的流允許您使用多個(gè)偵聽(tīng)器陨界。我們之前創(chuàng)建的流只能有一個(gè)監(jiān)聽(tīng)器; 它們被稱(chēng)為單訂閱流。
代碼示例
@override
void initState() {
super.initState();
stream();
}
final StreamController controller = StreamController.broadcast(); //add a .broadcast()
stream() {
controller.stream.where((data) => (data is String)).listen((data) {
print("DataReceived: " + data);
}, onDone: () {
print("Task 1 Done");
}, onError: (error) {
print("Some Error");
});
controller.stream.where((data) => (data is int)).listen((data) {
print("DataReceived: " + data.toString());
}, onDone: () {
print("Task 2 Done");
});
controller.stream.where((data) => (data is Map)).listen((data) {
print(data);
}, onDone: () {
print("Task 3 Done");
});
controller.sink.add('random string');
controller.sink.add(1234);
controller.sink.add({'key 1': 'value A', 'key 2': 'value B'});
controller.close();
}
輸出
DataReceived: random string
DataReceived: 1234
{key 1: value A, key 2: value B}
Task 1 Done
Task 2 Done
Task 3 Done
在這里痛阻,我們初始化一個(gè)StreamController
帶有.broadcast()
那么菌瘪,我們監(jiān)聽(tīng)流三個(gè)不同的時(shí)間。請(qǐng)注意阱当,我們.where()
在偵聽(tīng)之前使用了一個(gè)方法麻车,這有助于我只監(jiān)聽(tīng)滿足給定條件的流中的數(shù)據(jù)缀皱。首先,我們只打印字符串动猬,然后是整數(shù)啤斗,然后是地圖。
現(xiàn)在您知道如何創(chuàng)建和使用流赁咙。我將寫(xiě)一篇單獨(dú)的文章钮莲,我們可以使用流在我們的屏幕上使用實(shí)際工作應(yīng)用程序繪制小部件!
翻譯自:https://medium.com/better-programming/async-programming-in-flutter-with-streams-c949f74c9cf9