رفرفة. التزامن والتوازي

مرحبا يا هابر! أقدم لكم ترجمة مقالة "العقود الآجلة - العزلة - حلقة الأحداث" التي كتبها ديدييه بيلينز حول عدم التزامن والتعددية في Dart(وعلى Flutterوجه الخصوص).


TLDR:  ,        .       Event Loop, Future  async/await (,  JavaScript),   otlin,  ,       . ,        .

وحول ترجمة المصطلحات. في اللغة المنطوقةنحن أقول "تيارات" ، "تداولات" ، "عقود آجلة" ، إلخ ، بينما تبدو هذه المصطلحات غريبة وغريبة في طباعتها.


في نفس الوقت ، Streamهو تيار ، Threadو- تيار. لا يتم حفظ السياق في هذه الحالة دائمًا. نفس العزلة ، حسب ذوقي ، تبدو طبيعية باللغة الروسية ، لذلك في مكان ما أستخدم الإملاء باللغة السيريلية ، وفي مكان ما في الأصل.


هنا وهناك بين قوسين بعد الكلمات الروسية لغتها الإنجليزية الأصلية ، والعكس بالعكس في بعض الأحيان.


المقدمة


في الآونة الأخيرة، وأنا غالبا ما تحصل المسائل ذات الصلة مفاهيم Future، async، await، Isolateوالتنفيذ المتوازي من التعليمات البرمجية.


بالإضافة إلى ذلك ، يواجه بعض المطورين مشاكل في فهم تسلسل تنفيذ التعليمات البرمجية الخاصة بهم.


قررت اغتنام الفرصة وتخصيص مقال لهذه القضايا. في الوقت نفسه ، سأحاول التخلص من الارتباك المرتبط بشكل رئيسي بمفاهيم و .


Dart - لغة واحدة مترابطة


, DartFlutter Dart.


Dart . . , .

, ( ), , .


void myBigLoop(){
    for (int i = 0; i < 1000000; i++){
        _doSomethingSynchronously();
    }
}

, myBigLoop() . , - , , .


Dart


Dart, , Event Loop.


Flutter- ( Dart-), — Thread, — (Isolate). , .


, :


  1. (Queues) MicroTask ()
    Event (), FIFO (.: first in first out, .. ,
    , ),
  2. main() ,
  3. Event Loop ( )

,
Event Loop
, : MicroTask Event.


Event Loop "" ,
"". ,
Dart-, "" :


void eventLoop(){
    while (microTaskQueue.isNotEmpty){
        fetchFirstMicroTaskFromQueue();
        executeThisMicroTask();
        return;
    }

    if (eventQueue.isNotEmpty){
        fetchFirstEventFromQueue();
        executeThisEventRelatedCode();
    }
}

, MicroTask Event. ?


MicroTask


, , - , Event Loop.


. - , - :


MyResource myResource;

    ...

    void closeAndRelease() {
        scheduleMicroTask(_dispose);
        _close();
    }

    void _close(){
        // ,     
        //   
        ...
    }

    void _dispose(){
        // ,    
        //   ,  _close()
        // 
    }

-, , . , scheduleMicroTask() 7 . Event.


Event


, :


  • ,
    • /
    • ...
  • Future

, , Event.


, MicroTask , Event Loop Event .


, Futures Event.


Futures


Future , ( ) - .


, Future:


  • , Dart
  • , Future,
    Event
  • Future (incomplete)
  • , ( Future)

, Future Event,
Event Loop .


( ) then()
catchError() Future.


, :


void main(){
    print('Before the Future');
    Future((){
        print('Running the Future');
    }).then((_){
        print('Future is complete');
    });
    print('After the Future');
}

, :


Before the Future
After the Future
Running the Future
Future is complete

:


  1. print('Before the Future')
  2. (){print('Running the Future');} Event
  3. print('After the Future')
  4. Event Loop 2
  5. , then()

:


Future , , Event Loop

(async)


async, Dart , :


  • Future
  • , await,
  • Future, await

, await , [ Future], .
Event Loop...


,
,


void main() async {
  methodA();
  await methodB();
  await methodC('main');
  methodD();
}

methodA(){
  print('A');
}

methodB() async {
  print('B start');
  await methodC('B');
  print('B end');
}

methodC(String from) async {
  print('C start from $from');

  Future((){                // <==     -  
    print('C running Future from $from');
  }).then((_){
    print('C end of Future from $from');
  });

  print('C end from $from');  
}

methodD(){
  print('D');
}

:


A
B start
C start from B
C end from B
B end
C start from main
C end from main
D
C running Future from B
C end of Future from B
C running Future from main
C end of Future from main

, methodC() . , , .


, methodD() , :


void main() async {
  methodA();
  await methodB();
  await methodC('main');
  methodD();  
}

methodA(){
  print('A');
}

methodB() async {
  print('B start');
  await methodC('B');
  print('B end');
}

methodC(String from) async {
  print('C start from $from');

  await Future((){                  // <==  
    print('C running Future from $from');
  }).then((_){
    print('C end of Future from $from');
  });
  print('C end from $from');  
}

methodD(){
  print('D');
}

:


A
B start
C start from B
C running Future from B
C end of Future from B
C end from B
B end
C start from main
C running Future from main
C end of Future from main
C end from main
D

, await Future methodC() .


:


, , Event Loop

. . method1method2? ?


void method1(){
  List<String> myArray = <String>['a','b','c'];
  print('before loop');
  myArray.forEach((String value) async {
    await delayedPrint(value);
  });  
  print('end of loop');
}

void method2() async {
  List<String> myArray = <String>['a','b','c'];
  print('before loop');
  for(int i=0; i<myArray.length; i++) {
    await delayedPrint(myArray[i]);
  }
  print('end of loop');
}

Future<void> delayedPrint(String value) async {
  await Future.delayed(Duration(seconds: 1));
  print('delayedPrint: $value');
}

: .


, method1 forEach() . , async ( Future). await, Event. , : print('end of loop'). Event Loop 3 .


method2, ( ) — .


, ,
Event Loop...



, Flutter? ?


, Isolate ().



, Isolate Dart Thread ().


Thread.


Flutter . .

Event Loop.


(MicroTask Event).


.


Dart.



, .


1.


() API, Dart.


1.1. 1:


, , , "" "" .


, , . SendPort ( , , /, ).


, "" " " , "". :


//
//   
//     
//    
//
SendPort newIsolateSendPort;

//
//   
//
Isolate newIsolate;

//
// ,    
//   
//
void callerCreateIsolate() async {
    //
    //   ReceivePort  
    // SendPort  
    //
    ReceivePort receivePort = ReceivePort();

    //
    //   
    //
    newIsolate = await Isolate.spawn(
        callbackFunction,
        receivePort.sendPort,
    );

    //
    //     ""
    //
    newIsolateSendPort = await receivePort.first;
}

//
//    
//
static void callbackFunction(SendPort callerSendPort){
    //
    //   SendPort   
    //  ""
    //
    ReceivePort newIsolateReceivePort = ReceivePort();

    //
    //  ""   SendPort  
    //
    callerSendPort.send(newIsolateReceivePort.sendPort);

    //
    //  
    //
}

:

1.2. 2:


, , :


//
// ,     
//   
// 
//     ""
//   String (   )
//
Future<String> sendReceive(String messageToBeSent) async {
    //
    //     
    //
    ReceivePort port = ReceivePort();

    //
    //   ,  
    //  ,   
    //   
    //
    newIsolateSendPort.send(
        CrossIsolatesMessage<String>(
            sender: port.sendPort,
            message: messageToBeSent,
        )
    );

    //
    //     
    //
    return port.first;
}

//
// Callback-    
//
static void callbackFunction(SendPort callerSendPort){
    //
    //   SendPort   
    //  
    //
    ReceivePort newIsolateReceivePort = ReceivePort();

    //
    //  ""   SendPort  
    //
    callerSendPort.send(newIsolateReceivePort.sendPort);

    //
    //  ,    ,
    //    
    //
    newIsolateReceivePort.listen((dynamic message){
        CrossIsolatesMessage incomingMessage = message as CrossIsolatesMessage;

        //
        //  
        //
        String newMessage = "complemented string " + incomingMessage.message;

        //
        //   
        //
        incomingMessage.sender.send(newMessage);
    });
}

//
//  
//
class CrossIsolatesMessage<T> {
    final SendPort sender;
    final T message;

    CrossIsolatesMessage({
        @required this.sender,
        this.message,
    });
}

1.3. 3:


, :


void dispose(){
    newIsolate?.kill(priority: Isolate.immediate);
    newIsolate = null;
}

1.4. — Stream


, "" "" (Streams). Single-Listener Stream ( ).


2. (One-shot computation)


, , Dart compute,


  • ,
  • — -
  • .

: ( ).

3.


, ,


(Platform-Channel communication) (main isolate). , .

, ,
.


Future


, :


  • (user friendliness)

, (user experiences lags), .


, :


  1. ,
    ( )
  2. ,
    , — Event Loop Futures
  3. ,
    , —

, , , Futures ( async-) — Futures Event Loop "" . , ( - , ).


, Future — , .


  • => Future
  • =>

:


  • JSON, (HttpRequest),
    => compute
  • : =>
  • ( ..) =>
  • : , , .


, , Event Loop .


من المهم أيضًا ألا ننسى أن Flutter( Dart) هو مؤشر ترابط واحد ، لذلك ، من أجل إرضاء المستخدمين ، يجب على المطورين التأكد من أن التطبيق سيعمل بسلاسة قدر الإمكان. Futuresو - أدوات قوية للمساعدة في تحقيق هذا الهدف.


حظا طيبا وفقك الله


All Articles