Asyncio рдХреЗ рдЕрдВрджрд░ рдХреНрдпрд╛ рд╣реИ

рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ, рдореИрдВ рдкрд╛рдардХ рдХреЛ рдЖрдордВрддреНрд░рд┐рдд рдХрд░рддрд╛ рд╣реВрдВ рдХрд┐ рд╡реЗ рдореЗрд░реЗ рд╕рд╛рде рдПрд╕рд┐рдВрдХреЛ рдХреЗ рдзрдиреБрд╖ рдореЗрдВ рдПрдХ рдорд╛рдореВрд▓реА рд░реЛрдорд╛рдВрдЪрдХ рдпрд╛рддреНрд░рд╛ рдХрд░реЗрдВ рддрд╛рдХрд┐ рдпрд╣ рд╕рдордЭ рд╕рдХреЗрдВ рдХрд┐ рдпрд╣ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдХреЛрдб рдирд┐рд╖реНрдкрд╛рджрди рдХреЛ рдХреИрд╕реЗ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИред рд╣рдо рдХреЙрд▓рдмреИрдХ рдореЗрдВ рдмрд╛рдзрд╛ рдбрд╛рд▓рддреЗ рд╣реИрдВ рдФрд░ рдШрдЯрдирд╛рдУрдВ рдХреА рдПрдХ рд╢реНрд░реГрдВрдЦрд▓рд╛ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдХреЛрд░рдЯрд╛рдЗрди рдореЗрдВ рдореБрдЦреНрдп рд╕рд╛рд░ рдХреЗ рдПрдХ рдЬреЛрдбрд╝реЗ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рднрд╛рдЧрддреЗ рд╣реИрдВред рдпрджрд┐ рдЖрдкрдХреЗ рдЕрдЬрдЧрд░ рдХреЗ рдирдХреНрд╢реЗ рдореЗрдВ рдЕрднреА рддрдХ рдпреЗ рдЖрдХрд░реНрд╖рдг рдирд╣реАрдВ рд╣реИрдВ, рддреЛ рдмрд┐рд▓реНрд▓реА рдХрд╛ рд╕реНрд╡рд╛рдЧрдд рдХрд░реЗрдВред


рд╢реБрд░реБрдЖрдд рдХреЗ рд▓рд┐рдП - рд╣рдорд╛рд░реЗ рд╕рд╛рдордиреЗ рдлреИрд▓реЗ рдХреНрд╖реЗрддреНрд░ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдПрдХ рд╕рдВрдХреНрд╖рд┐рдкреНрдд рд╕рдВрджрд░реНрдн


asyncio рдПрдХ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ I / O рдкреБрд╕реНрддрдХрд╛рд▓рдп рд╣реИ, рдЬреЛ pep3153 рдХреЗ рдЕрдиреБрд╕рд╛рд░, рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдврд╛рдВрдЪреЗ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдорд╛рдирдХреАрдХреГрдд рдврд╛рдВрдЪрд╛ рдкреНрд░рджрд╛рди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рдерд╛ред pep3156 рднреА рдЙрд╕реЗ рдкрд╣рд▓реЗ рд╕реЗ рдореМрдЬреВрдж рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдлреНрд░реЗрдо (рдЯреНрд╡рд┐рд╕реНрдЯреЗрдб, рдЯреЛрд░реНрдиреЗрдбреЛ, рдЧреЗрд╡реЗрдВрдЯ) рдореЗрдВ рдмреЗрд╣рдж рд╕рд░рд▓ рдПрдХреАрдХрд░рдг рдкреНрд░рджрд╛рди рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрддрд╛рддрд╛ рд╣реИред рдЬреИрд╕рд╛ рдХрд┐ рд╣рдо рдЕрдм рдирд┐рд░реАрдХреНрд╖рдг рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЗрди рд▓рдХреНрд╖реНрдпреЛрдВ рдХреЛ рд╕рдлрд▓рддрд╛рдкреВрд░реНрд╡рдХ рд╣рд╛рд╕рд┐рд▓ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ - рдПрдХ рдирдпрд╛ рдПрд╕рд┐рдВрдХреЛ-рдЖрдзрд╛рд░рд┐рдд рдврд╛рдВрдЪрд╛ рджрд┐рдЦрд╛рдИ рджрд┐рдпрд╛: aiohttp , Tornado рдореЗрдВ AsyncioMainLoop рд╕рдВрд╕реНрдХрд░рдг 5.0 рд╕реЗ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдИрд╡реЗрдВрдЯ рд▓реВрдк рд╣реИ, рдЯреНрд╡рд┐рд╕реНрдЯреЗрдб рдПрд╕рд┐рдирд╕рд┐рдПрд╕реЗрдХреНрдЯрд░ рдореЗрдВ рд╕рдВрд╕реНрдХрд░рдг 16.5.0 рд╕реЗ рдЙрдкрд▓рдмреНрдз рд╣реИ, рдФрд░ рдЧреАрд╡реЗрдВрдЯ рдХреЗ рд▓рд┐рдП рдПрдХ рддреГрддреАрдп-рдкрдХреНрд╖ рдЕрдирдЗрд╡реЗрдВрдЯ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рд╣реИред ред


asyncio рдПрдХ рд╣рд╛рдЗрдмреНрд░рд┐рдб рд▓рд╛рдЗрдмреНрд░реЗрд░реА рд╣реИ рдЬреЛ рдПрдХ рд╕рд╛рде рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдХреЛрдб рдирд┐рд╖реНрдкрд╛рджрди рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рджреЛ рджреГрд╖реНрдЯрд┐рдХреЛрдгреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ: рдХреЙрд▓рдмреИрдХ рдкрд░ рдХреНрд▓рд╛рд╕рд┐рдХ рдФрд░, рдХреЛрд░рдЖрдЙрдЯ рдкрд░ рдЕрдкреЗрдХреНрд╖рд╛рдХреГрдд рдирдП (рдХрдо рд╕реЗ рдХрдо рдЕрдЬрдЧрд░ рдХреЗ рд▓рд┐рдП)ред рдпрд╣ рддреАрди рдореБрдЦреНрдп рд╕рд╛рд░ рдкрд░ рдЖрдзрд╛рд░рд┐рдд рд╣реИ, рдЬреЛ рддреАрд╕рд░реЗ рдкрдХреНрд╖ рдХреЗ рдврд╛рдВрдЪреЗ рдореЗрдВ рдореМрдЬреВрдж рдЕрдореВрд░реНрдд рддрддреНрд╡реЛрдВ рдХреЗ рдЕрдиреБрд░реВрдк рд╣реИрдВ:


  • рдкреНрд▓рдЧ рдХрд░рдиреЗ рдпреЛрдЧреНрдп рдЗрд╡реЗрдВрдЯ рд▓реВрдк
    рдкреНрд▓рдЧ рдХрд░рдиреЗ рдпреЛрдЧреНрдп рдЗрд╡реЗрдВрдЯ рд▓реВрдкред рдкреНрд▓рдЧ рдХрд░рдиреЗ рдпреЛрдЧреНрдп рдХрд╛ рдЕрд░реНрде рд╣реИ рдХрд┐ рдЗрд╕реЗ рдХреЛрдб рдХреА рджреЛ рдкрдВрдХреНрддрд┐рдпреЛрдВ рдореЗрдВ рдПрдХ рджреВрд╕рд░реЗ рдХреЗ рд╕рд╛рде рдмрджрд▓ рджрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдЬреЛ рд╕рдорд╛рди рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИред рдЕрдм рдХрд╛рдореЗрдЪреНрдЫрд╛ ( uvloop ) рдХреЗ рд╢реАрд░реНрд╖ рдкрд░ рд╕рд╛рдЗрдерди рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╣реИрдВ рдФрд░ рдЬрдВрдЧ рдореЗрдВ ( asyncio-tokio ) ред
  • рднрд╡рд┐рд╖реНрдп
    рдСрдкрд░реЗрд╢рди рдХрд╛ рдкрд░рд┐рдгрд╛рдо, рдЬреЛ рднрд╡рд┐рд╖реНрдп рдореЗрдВ рдЙрдкрд▓рдмреНрдз рд╣реЛрдЧрд╛ред рдХреЙрд░рдЖрдЙрдЯ рдореЗрдВ рдХреЙрд▓рдмреИрдХ рдирд┐рд╖реНрдкрд╛рджрди рдХрд╛ рдкрд░рд┐рдгрд╛рдо рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИред
  • рдХрд╛рд░реНрдп
    рдЗрд╡реЗрдВрдЯ рд▓реВрдк рдкрд░ рдХреЙрд░рдЖрдЙрдЯ рдЪрд▓рд╛рдиреЗ рдХреЗ рд▓рд┐рдП рднрд╡рд┐рд╖реНрдп рдХрд╛ рдПрдХ рд╡рд┐рд╢реЗрд╖ рдЙрдкрд╡рд░реНрдЧред

рдЪрд▓реЛ рдЪрд▓рддреЗ рд╣реИрдВ!


рдШрдЯрдирд╛рдУрдВ рдХрд╛ рдЪрдХреНрд░ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХрд╛ рдореБрдЦреНрдп рдШрдЯрдХ рд╣реИ, рдЗрд╕рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЪрд▓рдиреЗ рд╡рд╛рд▓реА рд╕рдбрд╝рдХреЛрдВ рдХреЗ рд╕рд╛рде, рдЗрд╕рдХреЗ рдХрд┐рд╕реА рднреА рдШрдЯрдХ рдХреЛ рдбреЗрдЯрд╛ рд╡рд┐рддрд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдпрд╣ рдмрдбрд╝рд╛ рдФрд░ рдЬрдЯрд┐рд▓ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдкрд╣рд▓реЗ рдЗрд╕рдХреЗ рд╕реНрдЯреНрд░рд┐рдк-рдбрд╛рдЙрди рд╕рдВрд╕реНрдХрд░рдг рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВред


# ~/inside_asyncio/base_loop.py import collections import random class Loop: def __init__(self): #     self.ready = collections.deque() def call_soon(self, callback, *args): #          self.ready.append((callback, args)) def run_until_complete(self, callback, *args): #         self.call_soon(callback, *args) #    -   #       while self.ready: ntodo = len(self.ready) #      #          for _ in range(ntodo): #       #        callback, args = self.ready.popleft() callback(*args) def callback(loop): print('') loop.call_soon(print, '') loop = Loop() loop.run_until_complete(callback, loop) 

рд╣рдорд╛рд░реЗ рдЫреЛрдЯреЗ рдХреЙрд▓рдмреИрдХ рдХреА рд╕рд╡рд╛рд░реА рдХрд░рддреЗ рд╣реБрдП, рд╣рдо call_soon рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╕рдбрд╝рдХ рдХреЛ рдорд╛рд░рддреЗ рд╣реИрдВ , рдХрддрд╛рд░ рдореЗрдВ рдкрд╣реБрдВрдЪрддреЗ рд╣реИрдВ рдФрд░ рдереЛрдбрд╝реЗ рдЗрдВрддрдЬрд╛рд░ рдХреЗ рдмрд╛рдж рд╣рдореЗрдВ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред


рдЦрд░рд╛рдм рдХреЙрд▓рдмреИрдХ рдПрдкрд┐рд╕реЛрдб


рдпрд╣ рдзреНрдпрд╛рди рджреЗрдиреЗ рдпреЛрдЧреНрдп рд╣реИ рдХрд┐ рдХреЙрд▓рдмреИрдХ рдЦрддрд░рдирд╛рдХ рдШреЛрдбрд╝реЗ рд╣реИрдВ - рдпрджрд┐ рд╡реЗ рдЖрдкрдХреЛ рд╕рдбрд╝рдХ рдХреЗ рдмреАрдЪ рдореЗрдВ рдлреЗрдВрдХрддреЗ рд╣реИрдВ, рддреЛ рдЕрдЬрдЧрд░ рджреБрднрд╛рд╖рд┐рдпрд╛ рдпрд╣ рд╕рдордЭрдиреЗ рдореЗрдВ рдорджрдж рдирд╣реАрдВ рдХрд░ рдкрд╛рдПрдЧрд╛ рдХрд┐ рдпрд╣ рдХрд╣рд╛рдВ рд╣реБрдЖ рдерд╛ред рдпрджрд┐ рдЖрдк рдореЗрд░реА рдмрд╛рдд рдкрд░ рд╡рд┐рд╢реНрд╡рд╛рд╕ рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ , рддреЛ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рдЙрд╕реА рд░рд╛рд╕реНрддреЗ рдкрд░ рд╕рд╡рд╛рд░реА рдХрд░реЗрдВ, рдЬреЛ рд╢рд╛рдпрдж рдХреЙрд▓рдмреИрдХ рдкрд░ рд╣реИ , рдЬреЛ рд▓рдЧрднрдЧ рдЖрдзреЗ рд╕рдордп рдХреЗ рдмрд╛рдж рдЦрддреНрдо рд╣реЛрддреА рд╣реИред


 # ~/inside_asyncio/base_loop.py def maybe_print(msg): if random.randint(0, 1): raise Exception(msg) else: print(msg) def starting_point(loop): #   print('') loop.call_soon(maybe_print, '') def main(loop): loop.call_soon(starting_point, loop) loop.call_soon(starting_point, loop) loop = Loop() loop.run_until_complete(main, loop) 

рдиреАрдЪреЗ рдкрд┐рдЫрд▓реЗ рдЙрджрд╛рд╣рд░рдг рдХрд╛ рдкреВрд░реНрдг рдЯреНрд░реЗрд╕рдмреИрдХ рд╣реИред рдЗрд╕ рддрдереНрдп рдХреЗ рдХрд╛рд░рдг рдХрд┐ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рд╢рд╛рдпрдж рдПрдХ рдШрдЯрдирд╛ рд▓реВрдк рджреНрд╡рд╛рд░рд╛ рд╢реБрд░реВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рдФрд░ рд╕реАрдзреЗ start_point рд╕реЗ рдирд╣реАрдВ, рдЯреНрд░реЗрд╕рдмреИрдХ рдЙрд╕ рдкрд░ рд╕рдорд╛рдкреНрдд рд╣реЛрддрд╛ рд╣реИ, run_until_complete рд╡рд┐рдзрд┐ рдореЗрдВред рдпрд╣ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдирд╛ рдЕрд╕рдВрднрд╡ рд╣реИ рдХрд┐ start_point рдРрд╕реЗ рдЯреНрд░реЗрд╕рдмреИрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП рдХреЛрдб рдореЗрдВ рдХрд╣рд╛рдВ рд╣реИ, рдЬреЛ рдХреЛрдбрд┐рдВрдЧ рдореЗрдВ рдХрдИ рд╕реНрдерд╛рдиреЛрдВ рдкрд░ start_point рд╕реНрдерд┐рдд рд╣реЛрдиреЗ рдкрд░ рдбрд┐рдмрдЧрд┐рдВрдЧ рдХреЛ рдмрд╣реБрдд рдЬрдЯрд┐рд▓ рдХрд░реЗрдЧрд╛ред


 $: python3 base_loop.py >>  #    >>  #    >>  #    >> Traceback (most recent call last): >> File "base_loop.py", line 42, in <module> >> loop.run_until_complete(main, loop) >> File "base_loop.py", line 17, in run_until_complete >> callback(*args) >> File "base_loop.py", line 29, in maybe_print >> raise Exception(msg) >> Exception:  #     

рди рдХреЗрд╡рд▓ рдкреВрд░реНрдг рдЯреНрд░реЗрд╕рдмреИрдХ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдмрд▓реНрдХрд┐ рдЕрдиреНрдп рднрд╛рд╖рд╛ рд╕реБрд╡рд┐рдзрд╛рдУрдВ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдирд┐рд░рдВрддрд░ рдХреЙрд▓ рд╕реНрдЯреИрдХ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЕрдкрд╡рд╛рдж рд╣реИрдВрдбрд▓рд┐рдВрдЧ рдЗрд╕ рдкрд░ рдЖрдзрд╛рд░рд┐рдд рд╣реИред рдиреАрдЪреЗ рджрд┐рдпрд╛ рдЧрдпрд╛ рдЙрджрд╛рд╣рд░рдг рдХрд╛рдо рдирд╣реАрдВ рдХрд░реЗрдЧрд╛, рдХреНрдпреЛрдВрдХрд┐ start_point рд╢реБрд░реВ рд╣реЛрдиреЗ рддрдХ, рдореБрдЦреНрдп рдХрд╛рд░реНрдп рдкрд╣рд▓реЗ рд╣реА рдирд┐рд╖реНрдкрд╛рджрд┐рдд рд╣реЛ рдЬрд╛рдПрдЧрд╛:


 # ~/inside_asyncio/base_loop.py def main(loop): try: loop.call_soon(starting_point, loop) loop.call_soon(starting_point, loop) except: pass Loop().run_until_complete(main, loop) 

рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЙрджрд╛рд╣рд░рдг рднреА рдХрд╛рдо рдирд╣реАрдВ рдХрд░реЗрдЧрд╛ред рдореБрдЦреНрдп рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рд╕рдВрджрд░реНрдн рдкреНрд░рдмрдВрдзрдХ рдлрд╝рд╛рдЗрд▓ рдХреЛ рдЦреЛрд▓рдиреЗ рдФрд░ рдмрдВрдж рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдЙрд╕рдХреЗ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рд╢реБрд░реВ рд╣реЛ рдЬрд╛рдПрдЧрд╛ред


 # ~/inside_asyncio/base_loop.py def main(loop): with open('file.txt', 'rb') as f: loop.call_soon(process_file, f) Loop().run_until_complete(main, loop) #       ,    =( 

рдирд┐рд░рдВрддрд░ рдХреЙрд▓ рд╕реНрдЯреИрдХ рдХреА рдХрдореА рдкрд░рд┐рдЪрд┐рдд рднрд╛рд╖рд╛ рд╕реБрд╡рд┐рдзрд╛рдУрдВ рдХреЗ рдЙрдкрдпреЛрдЧ рдХреЛ рд╕реАрдорд┐рдд рдХрд░рддреА рд╣реИред Asyncio рдореЗрдВ рдЗрд╕ рдХрдореА рдХреЛ рдЖрдВрд╢рд┐рдХ рд░реВрдк рд╕реЗ рджрд░рдХрд┐рдирд╛рд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдореБрдЭреЗ рдмрд╣реБрдд рд╕рд╛рд░реЗ рдЕрддрд┐рд░рд┐рдХреНрдд рдХреЛрдб рдЬреЛрдбрд╝рдиреЗ рдкрдбрд╝реЗ рдЬреЛ рд╕реАрдзреЗ рдЙрд╕ рдХрд╛рд░реНрдп рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рдирд╣реАрдВ рдереЗ рдЬреЛ рдЗрд╕реЗ рд╣рд▓ рдХрд░ рд░рд╣рд╛ рдерд╛ред рдЕрдзрд┐рдХрд╛рдВрд╢ рднрд╛рдЧ рдХреЗ рд▓рд┐рдП рдпрд╣ рдХреЛрдб, рдЙрджрд╛рд╣рд░рдгреЛрдВ рдореЗрдВ рдЧрд╛рдпрдм рд╣реИ - рд╡реЗ рдЗрд╕рдХреЗ рдмрд┐рдирд╛ рдХрд╛рдлреА рдЬрдЯрд┐рд▓ рд╣реИрдВред


рдШрдЯрдирд╛рдУрдВ рдХреЗ рдЪрдХреНрд░ рд╕реЗ рд▓реЗрдХрд░ рдмрд╛рд╣рд░реА рджреБрдирд┐рдпрд╛ рдФрд░ рдкреАрдЫреЗ рддрдХ


рдЗрд╡реЗрдВрдЯ рд▓реВрдк рдШрдЯрдирд╛рдУрдВ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдСрдкрд░реЗрдЯрд┐рдВрдЧ рд╕рд┐рд╕реНрдЯрдо рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдмрд╛рд╣рд░реА рджреБрдирд┐рдпрд╛ рдХреЗ рд╕рд╛рде рд╕рдВрдЪрд╛рд░ рдХрд░рддрд╛ рд╣реИред рдХреЛрдб рдЬреЛ рдЬрд╛рдирддрд╛ рд╣реИ рдХрд┐ рдЗрд╕рдХреЗ рд╕рд╛рде рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рдирд╛ рд╣реИ, рдПрдХ рдорд╛рдирдХ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдореЙрдбреНрдпреВрд▓ рджреНрд╡рд╛рд░рд╛ рдкреНрд░рджрд╛рди рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬрд┐рд╕реЗ рдЪрдпрдирдХрд░реНрддрд╛ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред рдпрд╣ рдЖрдкрдХреЛ рдСрдкрд░реЗрдЯрд┐рдВрдЧ рд╕рд┐рд╕реНрдЯрдо рдХреЛ рдпрд╣ рдмрддрд╛рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ рдХрд┐ рд╣рдо рдХрд┐рд╕реА рдкреНрд░рдХрд╛рд░ рдХреА рдШрдЯрдирд╛ рдХреА рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░ рд░рд╣реЗ рд╣реИрдВ, рдФрд░ рдлрд┐рд░ рдкреВрдЫреЗрдВ рдХрд┐ рдХреНрдпрд╛ рд╣реБрдЖред рдиреАрдЪреЗ рджрд┐рдП рдЧрдП рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, рдЕрдкреЗрдХреНрд╖рд┐рдд рдШрдЯрдирд╛ рдХреЛ рд╕реЙрдХреЗрдЯ рдХреА рдЙрдкрд▓рдмреНрдзрддрд╛ рдкрдврд╝реА рдЬрд╛рдПрдЧреАред


рдШрдЯрдирд╛ рдкрд╛рд╢
 # ~/inside_asyncio/event_loop.py import selectors import socket import collections from future import Future from handle import Handle from task import Task class EventLoop: def __init__(self): self.ready = collections.deque() #   self.selector = selectors.DefaultSelector() def add_reader(self, sock, callback): #       # : # , #         #           self.selector.register( sock, socket.EVENT_READ, (self._accept_conn, sock, callback) ) def _accept_conn(self, sock, callback): #    conn, addr = sock.accept() conn.setblocking(False) #      self.selector.register( conn, socket.EVENT_READ, (callback, conn) ) def run_until_complete(self, callback, *args): self.call_soon(callback, *args) #           -  while self.ready or self.selector.get_map(): ntodo = len(self._ready) for _ in range(ntodo): callback, args = self.ready.popleft() callback(*args) #       for key, events in self.selector.select(timeout=0): #          callback, *args = key.data #       self.call_soon(callback, *args) def call_soon(self, callback, *args): self.ready.append((callback, args)) def print_data(conn): print(conn.recv(1000)) def main(loop): #   sock = socket.socket() #     8086  sock.bind(('localhost', 8086)) sock.listen(100) sock.setblocking(False) #      loop.add_reader(sock, print_data) loop = EventLoop() #    loop.run_until_complete(main, loop) 

рдмрд╛рд╣рд░реА рджреБрдирд┐рдпрд╛ рдХрд╛ рдПрдХ рд╕рдВрджреЗрд╢рд╡рд╛рд╣рдХ рдЕрдкрдирд╛ рд╕рдВрджреЗрд╢ рдпрд╛ рдЪрдпрдирдХрд░реНрддрд╛ рдореЗрдВ рдкрд╛рд░реНрд╕рд▓ рдЫреЛрдбрд╝ рджреЗрддрд╛ рд╣реИ, рдФрд░ рдЪрдпрдирдХрд░реНрддрд╛ рдЗрд╕реЗ рдкреНрд░рд╛рдкреНрддрдХрд░реНрддрд╛ рдХреЛ рджреЗ рджреЗрддрд╛ рд╣реИред рдЕрдм рдИрд╡реЗрдВрдЯ рд▓реВрдк рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕реЙрдХреЗрдЯ рд╕реЗ рдкрдврд╝рдирд╛ рд╕рдВрднрд╡ рд╣реИред рдпрджрд┐ рдЖрдк рдЗрд╕ рдХреЛрдб рдХреЛ рдЪрд▓рд╛рддреЗ рд╣реИрдВ рдФрд░ netcat рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХрдиреЗрдХреНрдЯ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдпрд╣ рдИрдорд╛рдирджрд╛рд░реА рд╕реЗ рд╡рд╣ рд╕рдм рдХреБрдЫ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░реЗрдЧрд╛ рдЬреЛ рдЗрд╕реЗ рднреЗрдЬрд╛ рдЬрд╛рдПрдЧрд╛ред


 $: nc localhost 8086 $: python3 event_loop.py "Hi there!" b'"Hi there!"\n' "Hello!" b'"Hello!"\n' "Answer me, please!" b'"Answer me, please!"\n' 

рд▓реЗрдЦ рдХреА рд╢реБрд░реБрдЖрдд рдореЗрдВ, рдпрд╣ рдХрд╣рд╛ рдЧрдпрд╛ рдерд╛ рдХрд┐ рдПрд╕рд┐рдВрдХреЛ рдПрдХ рд╣рд╛рдЗрдмреНрд░рд┐рдб рд▓рд╛рдЗрдмреНрд░реЗрд░реА рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рдХреЙрд▓реЗрдпреВрдЯ рдХреЙрд▓рдмреИрдХ рдХреЗ рд╢реАрд░реНрд╖ рдкрд░ рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВред рдЗрд╕ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рджреЛ рд╢реЗрд╖ рдореБрдЦреНрдп рд╕рд╛рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ: рдХрд╛рд░реНрдп рдФрд░ рднрд╡рд┐рд╖реНрдп ред рдЕрдЧрд▓рд╛, рдЗрди рд╕рд╛рд░ рдХреЗ рдХреЛрдб рджрд┐рдЦрд╛рдП рдЬрд╛рдПрдВрдЧреЗ, рдФрд░ рдлрд┐рд░, рдШрдЯрдирд╛рдУрдВ рдХреЗ рдЕрдкрдиреЗ рдЪрдХреНрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП, рдХреЛрд░рдЯрд╛рдЗрди рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВред


рднрд╡рд┐рд╖реНрдп


рдиреАрдЪреЗ рднрд╡рд┐рд╖реНрдп рд╡рд░реНрдЧ рдХреЗ рд▓рд┐рдП рдХреЛрдб рд╣реИред рдпрд╣ рдЖрд╡рд╢реНрдпрдХ рд╣реИ рддрд╛рдХрд┐ рдХреЙрд░рдЯрд┐рди рдореЗрдВ рдЖрдк рдХреЙрд▓рдмреИрдХ рдкреВрд░рд╛ рд╣реЛрдиреЗ рддрдХ рдЗрдВрддрдЬрд╛рд░ рдХрд░ рд╕рдХреЗрдВ рдФрд░ рдЙрд╕рдХрд╛ рдкрд░рд┐рдгрд╛рдо рдкрд╛ рд╕рдХреЗрдВред


рднрд╡рд┐рд╖реНрдп
 # ~/inside_asyncio/future.py import sys from asyncio import events, CancelledError class Future: #        _state = 'PENDING' # FINISHED, CANCELLED #          Future #          _source_traceback = None #            _callbacks = [] #           _exception = None #           _loop = None #     _result = None def __init__(self, loop): self._loop = loop self._source_traceback = events.extract_stack(sys._getframe(1)) def add_done_callback(self, callback): #        self._callbacks.append(callback) def _schedule_callbacks(self): #         for callback in self._callbacks: self._loop.call_soon(callback, self) self._callbacks[:] = [] #            Future #    -     def set_exception(self, exception): #       self._exception = exception #   self._state = 'FINISHED' #      self._schedule_callbacks() def set_result(self, result): #         self._result = result self._state = 'FINISHED' self._schedule_callbacks() def cancel(self): #       self._state = 'CANCELLED' self._schedule_callbacks() def result(self): #     #         if self._state == 'CANCELLED': raise CancelledError #         if self._exception is not None: raise self._exception #    return self._result def __await__(self): #  ,    await #        if self._state == 'PENDING': yield self #     return self.result() 

рдХрд╛рд░реНрдп


рдпрд╣ рднрд╡рд┐рд╖реНрдп рдХрд╛ рдПрдХ рд╡рд┐рд╢реЗрд╖ рдЙрдкрд╡рд░реНрдЧ рд╣реИред рдХреЙрд▓рдмреИрдХ рдИрд╡реЗрдВрдЯ рд▓реВрдк рдкрд░ рдХреЛрд░рдЖрдЙрдЯреНрд╕ рдХреЛ рдЪрд▓рд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред


рдХрд╛рд░реНрдп
 # ~/inside_asyncio/task.py from asyncio import futures from future import Future class Task(Future): def __init__(self, coro, *, loop=None): super().__init__(loop=loop) #    self._coro = coro def _step(self, exc=None): #    ,     try: if exc is None: #        None #        result = self._coro.send(None) else: #        self._coro.throw(exc) except StopIteration: result = None except Exception as exc: self.set_exception(exc) else: #   Future      # wakeup      if isinstance(result, Future): result.add_done_callback(self._wakeup) #     step     elif result is None: self._loop.call_soon(self._step) def _wakeup(self, future): #     Future       Task #   try: future.result() except Exception as exc: self._step(exc) #        Future else: self._step() 

рдШрдЯрдирд╛рдУрдВ рдХрд╛ рдПрдХ рдЪрдХреНрд░ рдЬреЛ рднрд╡рд┐рд╖реНрдп рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░ рд╕рдХрддрд╛ рд╣реИ


рдлреНрдпреВрдЪрд░ рдХреЗ рд╕рд╛рде EventLoop
 # ~/inside_asyncio/future_event_loop.py import selectors from selectors import EVENT_READ, EVENT_WRITE import socket import collections from future import Future from task import Task class EventLoop: def __init__(self): self._ready = collections.deque() self.selector = selectors.DefaultSelector() def run_until_complete(self, callback, *args): self.call_soon(callback, *args) while self._ready or self.selector.get_map(): ntodo = len(self._ready) for _ in range(ntodo): callback, args = self._ready.popleft() callback(*args) for key, events in self.selector.select(timeout=0): callback, *args = key.data self.call_soon(callback, *args) def call_soon(self, callback, *args): self._ready.append((callback, args)) #      Future def sock_accept(self, sock, fut=None): #       #  Future     fut = fut if fut else Future(loop=self) try: #     conn, address = sock.accept() conn.setblocking(False) except (BlockingIOError, InterruptedError): #     #      #   Future    self.selector.register( sock, EVENT_READ, (self.sock_accept, sock, fut) ) except Exception as exc: fut.set_exception(exc) self.selector.unregister(sock) else: #    #   Future    fut.set_result((conn, address)) self.selector.unregister(sock) return fut def sock_recv(self, sock, n, fut=None): #       #      , #     ,      fut = fut if fut else Future(loop=self) try: data = sock.recv(n) except (BlockingIOError, InterruptedError): self.selector.register( sock, EVENT_READ, (self.sock_recv, sock, n, fut) ) except Exception as exc: fut.set_exception(exc) self.selector.unregister(sock) else: fut.set_result(data) self.selector.unregister(sock) return fut async def main(loop): sock = socket.socket() sock.bind(('localhost', 8080)) sock.listen(100) sock.setblocking(False) #    conn, addr = await loop.sock_accept(sock) #     result = await loop.sock_recv(conn, 1000) print(result) loop = EventLoop() #    Task task = Task(coro=main(loop), loop=loop) #         loop.run_until_complete(task._step) 

рдЪрд▓реЛ рдЖрдЧреЗ рдмрдврд╝рддреЗ рд╣реИрдВ


рдЕрдм рджреЗрдЦрддреЗ рд╣реИрдВ рдХрд┐ рдХреЛрд░рдЯрд╛рдЗрди рдореЗрди рдХреЛ рдХреИрд╕реЗ рдЕрдВрдЬрд╛рдо рджрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛:


рдХреНрд░рд┐рдпрд╛рдиреНрд╡рдпрди
 __________________________________________________________________ class EventLoop: def run_until_complete(self, callback, *args): # task._step    self.call_soon(callback, *args) while self._ready or self.selector.get_map(): ntodo = len(self._ready) for _ in range(ntodo): callback, args = self._ready.popleft() #     callback(*args) # task._step() ___________________________________________________________________ clsss Task: def _step(self, exc=None): try: if exc is None: #  None   result = self._coro.send(None) else: ___________________________________________________________________ async def main(loop): #      #   sock = socket.socket() sock.bind(('localhost', 8080)) sock.listen(100) sock.setblocking(False) #         conn, addr = await loop.sock_accept(sock) result = await loop.sock_recv(conn, 1000) print(result) ___________________________________________________________________ class EventLoop: def sock_accept(self, sock, fut=None): #   Future fut = fut if fut else Future(loop=self) try: #     conn, address = sock.accept() conn.setblocking(False) except (BlockingIOError, InterruptedError): #     #      #   Future    self.selector.register( sock, EVENT_READ, (self.sock_accept, sock, fut) ) except Exception as exc: -------------------------------------------- self.selector.unregister(sock) #  Future   return fut ___________________________________________________________________ async def main(loop): sock = socket.socket() sock.bind(('localhost', 8080)) sock.listen(100) sock.setblocking(False) #   await   __await__  Future conn, addr = await loop.sock_accept(sock) result = await loop.sock_recv(conn, 1000) print(result) ___________________________________________________________________ class Future: def __await__(self): #   Future         if self._state == 'PENDING': yield self return self.result() ___________________________________________________________________ class Task(Future): def _step(self, exc=None): try: if exc is None: #           None result = self._coro.send(None) # result = fut -------------------------------- else: #  Future      # wakeup      if isinstance(result, Future): result.add_done_callback(self._wakeup) elif result is None: self._loop.call_soon(self._step) #      -    Task  Future #    #               ___________________________________________________________________ class EventLoop: def run_until_complete(self, callback, *args): self.call_soon(callback, *args) while self._ready or self.selector.get_map(): ntodo = len(self._ready) for _ in range(ntodo): callback, args = self._ready.popleft() callback(*args) for key, events in self.selector.select(timeout=0): #    callback, *args = key.data self.call_soon(callback, *args) # loop.sock_accept(sock, fut) ___________________________________________________________________ class EventLoop: def sock_accept(self, sock, fut=None): fut = fut if fut else Future(loop=self) try: #    conn, address = sock.accept() conn.setblocking(False) except (BlockingIOError, InterruptedError): -------------------------------- else: #   Future fut.set_result((conn, address)) self.selector.unregister(sock) return fut ___________________________________________________________________ class Future: def set_result(self, result): #   self._result = result #   self._state = 'FINISHED' #      self._schedule_callbacks() def _schedule_callbacks(self): for callback in self._callbacks: #         task.wakeup self._loop.call_soon(callback, self) # (task.wakeup, fut) self._callbacks[:] = [] ___________________________________________________________________ class EventLoop: def run_until_complete(self, callback, *args): self.call_soon(callback, *args) while self._ready or self.selector.get_map(): ntodo = len(self._ready) for _ in range(ntodo): callback, args = self._ready.popleft() #      #    task.wakeup callback(*args) # task.wakeup(fut) ___________________________________________________________________ class Task(Future): def _wakeup(self, future): try: future.result() except Exception as exc: self._step(exc) else: #   Future      task._step self._step() def _step(self, exc=None): try: if exc is None: #       None result = self._coro.send(None) else: ___________________________________________________________________ async def main(loop): sock = socket.socket() sock.bind(('localhost', 8080)) sock.listen(100) sock.setblocking(False) #   await   __awai__   conn, addr = await loop.sock_accept(sock) result = await loop.sock_recv(conn, 1000) print(result) ___________________________________________________________________ class Future: def __await__(self): if self._state == 'PENDING': yield self #   Future    return self.result() ___________________________________________________________________ async def main(loop): sock = socket.socket() sock.bind(('localhost', 8080)) sock.listen(100) sock.setblocking(False) #    Future    conn  addr conn, addr = await loop.sock_accept(sock) result = await loop.sock_recv(conn, 1000) print(result) 

рдЗрд╕ рд╕рд░рд▓ рддрд░реАрдХреЗ рд╕реЗ, рдПрд╕рд┐рдВрд╕реАрдУ рдХреЛрд░рдЯрд╛рдЗрди рдХрд░рддрд╛ рд╣реИред


рдкрд░рд┐рдгрд╛рдо


рдПрд╕рд┐рдВрд╕реАрдУ рдмрдирд╛рдиреЗ рдХрд╛ рд▓рдХреНрд╖реНрдп рд╕рдлрд▓рддрд╛рдкреВрд░реНрд╡рдХ рд╣рд╛рд╕рд┐рд▓ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдЗрд╕рдиреЗ рди рдХреЗрд╡рд▓ рдЕрдиреБрдХреВрд▓рддрд╛ рдХреА рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд┐рдпрд╛, рдмрд▓реНрдХрд┐ рд╕рдореБрджрд╛рдп рдореЗрдВ рдкреНрд░рддрд┐рд╕реНрдкрд░реНрдзреА рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдореЗрдВ рд░реБрдЪрд┐ рдореЗрдВ рднреА рднрд╛рд░реА рд╡реГрджреНрдзрд┐ рд╣реБрдИред рдмрд╛рд░рд┐рд╢ рдХреЗ рдмрд╛рдж рдорд╢рд░реВрдо рдХреА рддрд░рд╣ рдирдП рд▓реЗрдЦ рдФрд░ рдкреБрд╕реНрддрдХрд╛рд▓рдп рджрд┐рдЦрд╛рдИ рджреЗрдиреЗ рд▓рдЧреЗред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, asyncio рдиреЗ рд╕реНрд╡рдпрдВ рднрд╛рд╖рд╛ рдХреЛ рдкреНрд░рднрд╛рд╡рд┐рдд рдХрд┐рдпрд╛: рджреЗрд╢реА рдХреЛрд░рдЖрдЙрдЯ рдФрд░ рдирдП async / рдкреНрд░рддреАрдХреНрд╖рд┐рдд рдХреАрд╡рд░реНрдб рдЗрд╕рдореЗрдВ рдЬреЛрдбрд╝реЗ рдЧрдПред рдЖрдЦрд┐рд░реА рдмрд╛рд░ 2003 рдореЗрдВ рдПрдХ рдирдпрд╛ рдХреАрд╡рд░реНрдб рдЬреЛрдбрд╝рд╛ рдЧрдпрд╛ рдерд╛, рдпрд╣ рдЙрдкрдЬ рдХреАрд╡рд░реНрдб рдерд╛ред


рдПрд╕рд┐рдВрдХреЛ рдмрдирд╛рдиреЗ рдХреЗ рд▓рдХреНрд╖реНрдпреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рдкрд╣рд▓реЗ рд╕реЗ рдореМрдЬреВрдж рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдврд╛рдВрдЪреЗ (рдЯреНрд╡рд┐рд╕реНрдЯреЗрдб, рдЯреЛрд░рдиреЗрдбреЛ, рдЧреЗрд╡реЗрдВрдЯ) рдореЗрдВ рдмреЗрд╣рдж рд╕рд░рд▓ рдПрдХреАрдХрд░рдг рдкреНрд░рджрд╛рди рдХрд░рдирд╛ рдерд╛ред рдЗрд╕ рд▓рдХреНрд╖реНрдп рд╕реЗ рддрд╛рд░реНрдХрд┐рдХ рд░реВрдк рд╕реЗ рд╕рд╛рдзрдиреЛрдВ рдХрд╛ рдЪреБрдирд╛рд╡ рд╣реЛрддрд╛ рд╣реИ: рдпрджрд┐ рдЕрдиреБрдХреВрд▓рддрд╛ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реЛрддреА, рддреЛ рдХреЛрд░рдЯрд╛рдЗрди рдХреЛ рдореБрдЦреНрдп рднреВрдорд┐рдХрд╛ рджреА рдЬрд╛рддреАред рдЗрд╕ рддрдереНрдп рдХреЗ рдХрд╛рд░рдг рдХрд┐ рдЬрдм рдХреЙрд▓рдмреИрдХ рдкрд░ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рд╣реЛрддреА рд╣реИ, рддреЛ рдХреЙрд▓ рдХреЗ рд▓рдЧрд╛рддрд╛рд░ рдвреЗрд░ рдХреЛ рдмрдирд╛рдП рд░рдЦрдирд╛ рдЕрд╕рдВрднрд╡ рд╣реЛрддрд╛ рд╣реИ, рдЗрд╕рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рднрд╛рд╖рд╛ рд╕реБрд╡рд┐рдзрд╛рдУрдВ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдирдХреЗ рдФрд░ рдХреЙрд░рдЖрдЙрдЯ рдХреЗ рдмреАрдЪ рдПрдХ рдЕрддрд┐рд░рд┐рдХреНрдд рдкреНрд░рдгрд╛рд▓реА рдмрдирд╛рдИ рдЬрд╛рдиреА рдереАред


рдЕрдм рдореБрдЦреНрдп рдкреНрд░рд╢реНрдиред рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреЗ рдПрдХ рд╕рд╛рдзрд╛рд░рдг рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рдпрд╣ рд╕рдм рдХреНрдпреЛрдВ рдкрддрд╛ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП, рдЬреЛ рдкреНрд░рд▓реЗрдЦрди рд╕реЗ рд╕рд┐рдлрд╛рд░рд┐рд╢реЛрдВ рдХрд╛ рдкрд╛рд▓рди рдХрд░рддрд╛ рд╣реИ рдФрд░ рдХреЗрд╡рд▓ рдХреЙрд░рдЖрдЙрдЯ рдФрд░ рдЙрдЪреНрдЪ-рд╕реНрддрд░реАрдп рдПрдкреАрдЖрдИ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ?
рдпрд╣рд╛рдБ StreamWriter рд╡рд░реНрдЧ рдкреНрд░рд▓реЗрдЦрди рдХрд╛ рдПрдХ рдЯреБрдХрдбрд╝рд╛ рд╣реИ



рдЗрд╕рдХрд╛ рдЙрджрд╛рд╣рд░рдг asyncio.open_connection рдлрд╝рдВрдХреНрд╢рди рджреНрд╡рд╛рд░рд╛ рд╡рд╛рдкрд╕ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ рдФрд░ рдХреЙрд▓рдмреИрдХ API рдХреЗ рд╢реАрд░реНрд╖ рдкрд░ async / рдкреНрд░рддреАрдХреНрд╖рд┐рдд API рд╣реИред рдФрд░ рдпреЗ рдХреЙрд▓рдмреИрдХ рдЗрд╕рд╕реЗ рдмрд╛рд╣рд░ рд░рд╣рддреЗ рд╣реИрдВред рд▓реЗрдЦрди рдФрд░ рд▓реЗрдЦрди рдХрд╛рд░реНрдп рд╕рдордХрд╛рд▓рд┐рдХ рд╣реИрдВ, рд╡реЗ рд╕реЙрдХреЗрдЯ рдкрд░ рд▓рд┐рдЦрдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рдпрджрд┐ рд╡рд╣ рд╡рд┐рдлрд▓ рд░рд╣рддрд╛ рд╣реИ, рддреЛ рд╡реЗ рдбреЗрдЯрд╛ рдХреЛ рдЕрдВрддрд░реНрдирд┐рд╣рд┐рдд рдмрдлрд░ рдореЗрдВ рдбрдВрдк рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рд░рд┐рдХреЙрд░реНрдб рдореЗрдВ рдХреЙрд▓рдмреИрдХ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВред рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдореВрд▓реНрдп рдкрд░ рдмрдлрд░ рдбреНрд░реЙрдк рдореЗрдВ рдбреЗрдЯрд╛ рдХреА рдорд╛рддреНрд░рд╛ рддрдХ рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░рдиреЗ рдХрд╛ рдЕрд╡рд╕рд░ рдкреНрд░рджрд╛рди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреЙрд░рдЯрд┐рди рдирд╛рд▓реА рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред


рдпрджрд┐ рдЖрдк рд▓рд┐рдЦрдиреЗ рдХреЗ рдХреЙрд▓ рдХреЗ рдмреАрдЪ рдирд╛рд▓реА рдХреЛ рдХреЙрд▓ рдХрд░рдирд╛ рднреВрд▓ рдЬрд╛рддреЗ рд╣реИрдВ, рддреЛ рдЖрдВрддрд░рд┐рдХ рдмрдлрд░ рдЕрд╢реЛрднрдиреАрдп рдЖрдХрд╛рд░ рддрдХ рдмрдврд╝ рд╕рдХрддрд╛ рд╣реИред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдпрджрд┐ рдЖрдк рдЗрд╕реЗ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрддреЗ рд╣реИрдВ, рддреЛ рдХреБрдЫ рдЕрдкреНрд░рд┐рдп рдХреНрд╖рдг рдмрдиреЗ рд░рд╣рддреЗ рд╣реИрдВред рдкрд╣рд▓рд╛: рдпрджрд┐ рд░рд┐рдХреЙрд░реНрдб "рдХреЙрд▓" рдкрд░ рдХреЙрд▓рдмреИрдХ рд╣реЛрддрд╛ рд╣реИ, рддреЛ рдЗрд╕ рдПрдкреАрдЖрдИ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдХреЛрд░рдЖрдЙрдЯ рдХреЛ рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХрд┐рд╕реА рднреА рддрд░рд╣ рд╕реЗ рдкрддрд╛ рдирд╣реАрдВ рдЪрд▓реЗрдЧрд╛ рдФрд░ рддрджрдиреБрд╕рд╛рд░, рдЗрд╕реЗ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рдирд╣реАрдВ рд╣реЛрдЧрд╛ред рджреВрд╕рд░рд╛: рдпрджрд┐ рдХреЛрд░рдЯрд╛рдЗрди "рдЯреВрдЯ рдЬрд╛рддрд╛ рд╣реИ", рддреЛ рд░рд┐рдХреЙрд░реНрдб рдХреЗ рдХреЙрд▓рдмреИрдХ рдХреЛ рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХрд┐рд╕реА рднреА рддрд░рд╣ рд╕реЗ рдкрддрд╛ рдирд╣реАрдВ рдЪрд▓реЗрдЧрд╛ рдФрд░ рдмрдлрд░ рд╕реЗ рдбреЗрдЯрд╛ рд▓рд┐рдЦрдирд╛ рдЬрд╛рд░реА рд░рдЦреЗрдЧрд╛ред


рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдХреЗрд╡рд▓ coroutines рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП, рдЗрд╕ рддрдереНрдп рдХреЗ рд▓рд┐рдП рддреИрдпрд╛рд░ рд░рд╣реЗрдВ рдХрд┐ рдХреЙрд▓рдмреИрдХ рдЦреБрдж рдХреЛ рдпрд╛рдж рджрд┐рд▓рд╛рдПрдЧрд╛ред


рдЖрдк рд╣рдорд╛рд░реЗ рдХреЙрд░реНрдкреЛрд░реЗрдЯ рдмреНрд▓реЙрдЧ рдПрдВрдЯрд┐рдбрд╛ рд╕реЙрдлреНрдЯрд╡реЗрдпрд░ рдХреЗ рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдХреЛрдб рд╕реЗ рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рддрд░реАрдХреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдкрдврд╝ рд╕рдХрддреЗ рд╣реИрдВред


PS eirnym , kurb , rasswet рдХреЗ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдХреЛ рдЯрд╛рдЗрдкреЛрд╕ рдФрд░ рдЕрд╢реБрджреНрдзрд┐рдпреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж

Source: https://habr.com/ru/post/hi453348/


All Articles