คำขอแบบอะซิงโครนัสกับคำขอ Python


142

ฉันลองตัวอย่างที่ให้ไว้ในเอกสารประกอบของไลบรารีคำขอสำหรับหลาม

ด้วยasync.map(rs)ฉันได้รับรหัสตอบกลับ แต่ฉันต้องการรับเนื้อหาของแต่ละหน้าที่ร้องขอ เช่นนี้ไม่ทำงาน:

out = async.map(rs)
print out[0].content

บางทีคำตอบที่คุณได้รับมีร่างกายที่ว่างเปล่า?
Mariusz Jamro

ได้ผลสำหรับฉัน โปรดโพสต์ข้อผิดพลาดแบบเต็มที่คุณได้รับ
Chewie

ไม่มีข้อผิดพลาด มันจะทำงานตลอดไปโดย URL การทดสอบที่ให้ไว้
trbck

เห็นได้ชัดว่ามันปรากฏขึ้นเมื่อฉันใช้ URL มากกว่า https http ทำงานได้ดี
trbck

ดูเหมือนว่าrequests-threadsมีอยู่ตอนนี้
OrangeDog

คำตอบ:


154

บันทึก

คำตอบด้านล่างไม่สามารถใช้ได้กับคำขอ v0.13.0 + ฟังก์ชันการทำงานแบบอะซิงโครนัสถูกย้ายไปที่grequestsหลังจากเขียนคำถามนี้ อย่างไรก็ตามคุณสามารถแทนที่requestsด้วยgrequestsด้านล่างและควรใช้งานได้

ฉันได้ทิ้งคำตอบนี้ไว้เพื่อสะท้อนถึงคำถามเดิมซึ่งเกี่ยวกับการใช้คำขอ <v0.13.0


ในการทำงานหลายอย่างด้วยasync.map อะซิงโครนัสคุณต้อง:

  1. กำหนดฟังก์ชั่นสำหรับสิ่งที่คุณต้องการทำกับแต่ละวัตถุ (งานของคุณ)
  2. เพิ่มฟังก์ชั่นนั้นเป็นเบ็ดกิจกรรมในคำขอของคุณ
  3. โทรหาasync.mapรายการคำขอ / การกระทำทั้งหมด

ตัวอย่าง:

from requests import async
# If using requests > v0.13.0, use
# from grequests import async

urls = [
    'http://python-requests.org',
    'http://httpbin.org',
    'http://python-guide.org',
    'http://kennethreitz.com'
]

# A simple task to do to each response object
def do_something(response):
    print response.url

# A list to hold our things to do via async
async_list = []

for u in urls:
    # The "hooks = {..." part is where you define what you want to do
    # 
    # Note the lack of parentheses following do_something, this is
    # because the response will be used as the first argument automatically
    action_item = async.get(u, hooks = {'response' : do_something})

    # Add the task to our list of things to do via async
    async_list.append(action_item)

# Do our list of things to do via async
async.map(async_list)

2
เป็นความคิดที่ดีที่ได้แสดงความคิดเห็นของคุณ: เนื่องจากปัญหาความเข้ากันได้ระหว่างคำขอล่าสุดและ grequests (ไม่มีตัวเลือก max_retries ในคำขอ 1.1.0) ฉันต้องปรับลดคำขอเพื่อเรียกใช้ async และฉันพบว่าการทำงานแบบอะซิงโครนัสถูกย้ายไปกับรุ่น 0.13+ ( pypi.python.org/pypi/requests )
outforawhile

1
คำถามโง่: การเพิ่มความเร็วในการใช้ grequests คืออะไรเมื่อเทียบกับการร้องของ่ายๆ? มีข้อ จำกัด อะไรบ้างเกี่ยวกับคำขอ เช่นจะใส่คำขอ 3,500 รายการใน async.map เป็นปกติหรือไม่
droope

10
from grequests import asyncไม่ทำงาน .. และคำจำกัดความของ dosomething นี้ทำงานได้สำหรับฉันdef do_something(response, **kwargs):ฉันพบได้จากstackoverflow.com/questions/15594015/ …
Allan Ruin

3
ถ้าการเรียกใช้ async.map ยังคงบล็อกอยู่ดังนั้นอะซิงโครนัสนี้จะเป็นอย่างไร? นอกจากคำขอที่ถูกส่งแบบอะซิงโครนัสการดึงข้อมูลยังคงเป็นแบบซิงโครนัส?
bryanph

3
แทนที่from requests import asyncด้วยการimport grequests as asyncทำงานสำหรับฉัน
Martin Thoma

80

asyncgrequestsคือตอนนี้โมดูลอิสระ

ดูที่นี่: https://github.com/kennethreitz/grequests

และมีวิธีที่เหมาะสำหรับการส่งคำขอ HTTP หลายรายการผ่าน Python หรือไม่

การติดตั้ง:

$ pip install grequests

การใช้งาน:

สร้างสแต็ค:

import grequests

urls = [
    'http://www.heroku.com',
    'http://tablib.org',
    'http://httpbin.org',
    'http://python-requests.org',
    'http://kennethreitz.com'
]

rs = (grequests.get(u) for u in urls)

ส่งสแต็ก

grequests.map(rs)

ผลดูเหมือนว่า

[<Response [200]>, <Response [200]>, <Response [200]>, <Response [200]>, <Response [200]>]

grequests ดูเหมือนจะไม่ได้ตั้งข้อ จำกัด สำหรับคำขอที่เกิดขึ้นพร้อมกันเช่นเมื่อมีการส่งคำขอจำนวนมากไปยังเซิร์ฟเวอร์เดียวกัน


11
ในส่วนที่เกี่ยวกับข้อ จำกัด ในคำขอที่เกิดขึ้นพร้อมกันคุณสามารถระบุขนาดพูลเมื่อเรียกใช้แผนที่ () / imap () ie grequests.map (rs, size = 20) เพื่อให้มี 20 grab พร้อมกัน
synthesizerpatel

1
ณ ตอนนี้สิ่งนี้ไม่สามารถใช้กับ python3 ได้ (gevent ล้มเหลวในการสร้าง v2.6 บน py3.4)
saarp

1
ฉันไม่ค่อยเข้าใจส่วน async หากฉันปล่อยให้results = grequests.map(rs)โค้ดหลังจากบรรทัดนี้ถูกบล็อกฉันจะเห็นเอฟเฟกต์ async ได้หรือไม่
Allan Ruin

47

ผมทดสอบทั้งคำขอฟิวเจอร์สและgrequests Grequests เร็วขึ้น แต่นำการปะของลิงและปัญหาเพิ่มเติมเกี่ยวกับการพึ่งพา การร้องขอ - ฟิวเจอร์ช้ากว่า grequests หลายครั้ง ฉันตัดสินใจที่จะเขียนของฉันเองและเพียงแค่ห่อคำขอไปยังThreadPoolExecutorและมันก็เกือบจะเร็วเท่ากับ grequests แต่ไม่มีการพึ่งพาจากภายนอก

import requests
import concurrent.futures

def get_urls():
    return ["url1","url2"]

def load_url(url, timeout):
    return requests.get(url, timeout = timeout)

with concurrent.futures.ThreadPoolExecutor(max_workers=20) as executor:

    future_to_url = {executor.submit(load_url, url, 10): url for url in     get_urls()}
    for future in concurrent.futures.as_completed(future_to_url):
        url = future_to_url[future]
        try:
            data = future.result()
        except Exception as exc:
            resp_err = resp_err + 1
        else:
            resp_ok = resp_ok + 1

มีข้อยกเว้นประเภทใดบ้างที่นี่
แฮร์รี่ช้า

requests.exceptions.Timeout
Hodza

2
ขอโทษฉันไม่เข้าใจคำถามของคุณ ใช้ URL เดียวเท่านั้นในหลายกระทู้? มีเพียงกรณีเดียวที่ DDoS โจมตี))
Hodza

1
ฉันไม่เข้าใจว่าทำไมคำตอบนี้มี upvotes มากมาย คำถาม OP เกี่ยวกับคำขอ async ThreadPoolExecutor เรียกใช้เธรด ใช่คุณสามารถทำการร้องขอในหลาย ๆ เธรด แต่นั่นจะไม่เป็นโปรแกรม async ดังนั้นฉันจึงเป็นคำตอบสำหรับคำถามเดิมได้อย่างไร
nagylzs

1
ที่จริงคำถามคือเกี่ยวกับวิธีการโหลด URL ในแบบคู่ขนาน และใช่ตัวจัดการเธรดพูลไม่ใช่ตัวเลือกที่ดีที่สุดจะดีกว่าถ้าใช้ async io แต่ใช้งานได้ดีใน Python และฉันไม่เข้าใจว่าทำไมไม่สามารถใช้เธรดเป็น async ได้ ถ้าคุณต้องการเรียกใช้งาน CPU ที่ผูกไว้แบบอะซิงโครนัส
Hodza

29

บางทีการร้องขอล่วงหน้าเป็นทางเลือกอื่น

from requests_futures.sessions import FuturesSession

session = FuturesSession()
# first request is started in background
future_one = session.get('http://httpbin.org/get')
# second requests is started immediately
future_two = session.get('http://httpbin.org/get?foo=bar')
# wait for the first request to complete, if it hasn't already
response_one = future_one.result()
print('response one status: {0}'.format(response_one.status_code))
print(response_one.content)
# wait for the second request to complete, if it hasn't already
response_two = future_two.result()
print('response two status: {0}'.format(response_two.status_code))
print(response_two.content)

มันเป็นยังแนะนำในเอกสารสำนักงาน หากคุณไม่ต้องการมีส่วนร่วมกับ gevent มันเป็นสิ่งที่ดี


1
หนึ่งในโซลูชั่นที่ง่ายที่สุด จำนวนคำขอที่เกิดขึ้นพร้อมกันสามารถเพิ่มได้โดยการกำหนดพารามิเตอร์ max_workers
Jose Cherian

1
มันคงจะดีถ้าได้เห็นตัวอย่างของมาตราส่วนนี้ดังนั้นเราไม่ได้ใช้ชื่อตัวแปรหนึ่งตัวต่อรายการเพื่อวนซ้ำ
user1717828

การมีหนึ่งกระทู้ต่อการร้องขอนั้นเป็นการสิ้นเปลืองทรัพยากร! มันเป็นไปไม่ได้ที่จะทำเช่น 500 คำขอพร้อมกันมันจะฆ่าซีพียูของคุณ สิ่งนี้ไม่ควรถูกมองว่าเป็นทางออกที่ดี
Corneliu Maftuleac

@CorneliuMaftuleac จุดที่ดี เกี่ยวกับการใช้เธรดคุณต้องดูแลอย่างแน่นอนและไลบรารีมีตัวเลือกเพื่อเปิดใช้งานเธรดพูลหรือพูลการประมวลผล ThreadPoolExecutor(max_workers=10)
Dreampuf

@Dreampuf กลุ่มการประมวลผลฉันเชื่อว่าจะยิ่งแย่ลง?
Corneliu Maftuleac

12

ฉันมีปัญหามากมายเกี่ยวกับคำตอบส่วนใหญ่ที่โพสต์ - พวกเขาอาจใช้ห้องสมุดที่เลิกใช้แล้วซึ่งได้รับการย้ายข้อมูลด้วยคุณสมบัติที่ จำกัด หรือเสนอวิธีแก้ปัญหาด้วยเวทมนตร์ที่มากเกินไปในการดำเนินการตามคำขอทำให้ยากที่จะจัดการข้อผิดพลาด หากพวกเขาไม่ได้อยู่ในหมวดหมู่ใดหมวดหนึ่งข้างต้นพวกเขาเป็นห้องสมุดบุคคลที่สามหรือเลิกใช้

โซลูชันบางตัวทำงานได้อย่างหมดจดในคำขอ HTTP แต่โซลูชันนั้นสั้นเกินไปสำหรับคำขอประเภทอื่น ๆ ซึ่งน่าหัวเราะ โซลูชันที่กำหนดเองสูงไม่จำเป็นที่นี่

เพียงใช้ไลบรารี่ในตัวของไพ ธ อนasyncioก็เพียงพอที่จะดำเนินการตามคำขอแบบอะซิงโครนัสทุกประเภทรวมถึงให้การไหลที่เพียงพอสำหรับการจัดการข้อผิดพลาดที่ซับซ้อน

import asyncio

loop = asyncio.get_event_loop()

def do_thing(params):
    async def get_rpc_info_and_do_chores(id):
        # do things
        response = perform_grpc_call(id)
        do_chores(response)

    async def get_httpapi_info_and_do_chores(id):
        # do things
        response = requests.get(URL)
        do_chores(response)

    async_tasks = []
    for element in list(params.list_of_things):
       async_tasks.append(loop.create_task(get_chan_info_and_do_chores(id)))
       async_tasks.append(loop.create_task(get_httpapi_info_and_do_chores(ch_id)))

    loop.run_until_complete(asyncio.gather(*async_tasks))

มันทำงานอย่างไรง่าย คุณกำลังสร้างชุดของงานที่คุณต้องการให้เกิดขึ้นแบบอะซิงโครนัสแล้วขอให้วงวนเพื่อดำเนินงานเหล่านั้นและออกเมื่อเสร็จสิ้น ไม่มีไลบรารีเพิ่มเติมที่ต้องขาดการบำรุงรักษาไม่จำเป็นต้องใช้ฟังก์ชัน


2
หากฉันเข้าใจถูกต้องสิ่งนี้จะบล็อกลูปของเหตุการณ์ในขณะที่ทำการโทร GRPC และ HTTP ดังนั้นหากการโทรเหล่านี้ใช้เวลาไม่กี่วินาทีจึงจะเสร็จสิ้นเหตุการณ์วนรอบทั้งหมดของคุณจะถูกบล็อกเป็นวินาที? เพื่อหลีกเลี่ยงนี้คุณจำเป็นต้องใช้ GRPC หรือ HTTP asyncห้องสมุดที่มี await response = requests.get(URL)จากนั้นคุณสามารถทำเช่น ไม่มี?
Coder Nr 23

น่าเสียดายที่เมื่อลองทำสิ่งนี้ฉันพบว่าการทำ wrapper รอบ ๆrequestsนั้นเร็วขึ้น (และในบางกรณีช้ากว่า) เพียงแค่เรียกรายการ URL พร้อมกัน เช่นการขอปลายทางที่ใช้เวลา 3 วินาทีในการตอบสนอง 10 ครั้งโดยใช้กลยุทธ์ด้านบนใช้เวลาประมาณ 30 วินาที หากคุณต้องการที่แท้จริงของประสิทธิภาพการทำงานของคุณจะต้องใช้สิ่งที่ต้องการasync aiohttp
DragonBobZ

@ DragonBobZ ในกรณีของฉันฉันเห็นการลดเวลา ~ 40% ประโยชน์หลักคือเพื่อให้สามารถทำงานที่จำเป็นในขณะที่รอสายต่อไป ในชุดข้อมูลของฉันฉันกำลังโทรนับร้อยดังนั้นมาตราส่วนอาจเป็นปัจจัยได้เช่นกัน
arshbot

@ CoderNr23 ใครบางคนสามารถแก้ไขฉันในเรื่องนี้ได้ แต่ iirc แม้จะมีไวยากรณ์นั้นการดำเนินงานเป็นแบบซิงโครนัสโดยพื้นฐาน - ลำดับของงานที่เกิดขึ้นเมื่อทำ async ในไพ ธ อนคุณเพียง แต่บรรจุแผนผังการทำงานแบบซิงโครนัสซึ่งจะถูกเรียกใช้งานด้วยตัวเริ่มต้นบางตัวrun_until_complete- นี่คือเว้นแต่คุณจะใช้โมดูลเธรดซึ่งมอบหมาย async ให้กับเลเยอร์ OS อ่านเพิ่มเติมเกี่ยวกับปัญหา GIL ใน python สำหรับข้อมูลเพิ่มเติม
arshbot

@arshbot ใช่ถ้างานของคุณไม่ตรงกันคุณจะเห็นความเร็วเพิ่มขึ้นแม้ว่าจะรอสายซิงโครนัสrequests.getก็ตาม แต่คำถามคือทำอย่างไรกับคำขอแบบอะซิงโครนัสกับrequestsห้องสมุดหลาม คำตอบนี้ไม่ได้เป็นอย่างนั้น
DragonBobZ

8

ฉันรู้ว่านี่ถูกปิดไประยะหนึ่งแล้ว แต่ฉันคิดว่ามันอาจมีประโยชน์ในการโปรโมตโซลูชัน async อื่นที่สร้างขึ้นในไลบรารีคำขอ

list_of_requests = ['http://moop.com', 'http://doop.com', ...]

from simple_requests import Requests
for response in Requests().swarm(list_of_requests):
    print response.content

เอกสารอยู่ที่นี่: http://pythonhosted.org/simple-requests/


@YSY รู้สึกอิสระที่จะโพสต์ปัญหา: github.com/ctheiss/simple-requests/issues ; ฉันใช้ห้องสมุดนี้หลายพันครั้งต่อวัน
Monkey Boson

บอสตันคุณจะจัดการกับข้อผิดพลาด 404/500 อย่างไร สิ่งที่เกี่ยวกับ https URL? จะซาบซ่าน snipping ที่สนับสนุนหลายพัน URL คุณช่วยวางตัวอย่างได้ไหม ขอบคุณ
YSY

@YSY โดยค่าเริ่มต้น 404/500 ข้อผิดพลาดยกข้อยกเว้น พฤติกรรมนี้สามารถถูกเขียนทับได้ (ดูpythonhosted.org/simple-requests/… ) URL ของ HTTPS นั้นยุ่งยากเนื่องจากการพึ่งพา gevent ซึ่งปัจจุบันมีข้อบกพร่องที่โดดเด่นในเรื่องนี้ ( github.com/gevent/gevent/issues/477 ) มี shim ในตั๋วที่คุณสามารถใช้งานได้ แต่มันจะยังคงโยนคำเตือนสำหรับเซิร์ฟเวอร์ SNI (แต่จะใช้งานได้) สำหรับเรื่องการจู่โจมฉันกลัวว่าประเพณีของฉันทั้งหมดจะอยู่ที่ บริษัท ของฉันและปิดลง แต่ฉันรับรองว่าคุณดำเนินการคำขอหลายพันรายการผ่านหลายสิบงาน
Monkey Boson

ห้องสมุดดูเพรียวบางเมื่อเทียบกับการโต้ตอบ Python3 + ใช้งานได้หรือไม่ ขออภัยไม่สามารถเห็นการกล่าวถึงใด ๆ
Isaac Philip

@Jethro ถูกต้องห้องสมุดจะต้องเขียนใหม่ทั้งหมดเนื่องจากเทคโนโลยีพื้นฐานแตกต่างกันมากใน Python 3 สำหรับตอนนี้ไลบรารีนั้น "สมบูรณ์" แต่ใช้ได้กับ Python 2 เท่านั้น
Monkey Boson

4
threads=list()

for requestURI in requests:
    t = Thread(target=self.openURL, args=(requestURI,))
    t.start()
    threads.append(t)

for thread in threads:
    thread.join()

...

def openURL(self, requestURI):
    o = urllib2.urlopen(requestURI, timeout = 600)
    o...

4
นี่คือคำขอ "ปกติ" ในกระทู้ ไม่ใช่ตัวอย่างที่แย่การซื้อนอกหัวข้อ
Nick

4

หากคุณต้องการใช้ asyncio คุณrequests-asyncจะได้รับฟังก์ชั่น async / await สำหรับrequests- https://github.com/encode/requests-async


2
ยืนยันใช้งานได้ดี ในหน้าโครงการมันบอกว่างานนี้ได้รับการแซงโดยโครงการต่อไปนี้github.com/encode/httpx
nurettin

2

ฉันได้ใช้การร้องขอของ python สำหรับการโทรแบบ async กับ gistub ของ github เป็นระยะเวลาหนึ่ง

ตัวอย่างเช่นดูรหัสที่นี่:

https://github.com/davidthewatson/flasgist/blob/master/views.py#L60-72

ไพ ธ อนรูปแบบนี้อาจไม่ใช่ตัวอย่างที่ชัดเจน แต่ฉันรับรองได้ว่าโค้ดใช้งานได้ แจ้งให้เราทราบหากสิ่งนี้ทำให้คุณสับสนและฉันจะบันทึกไว้


2

คุณสามารถใช้httpxสำหรับการที่

import httpx

async def get_async(url):
    async with httpx.AsyncClient() as client:
        return await client.get(url)

urls = ["http://google.com", "http://wikipedia.org"]

# Note that you need an async context to use `await`.
await asyncio.gather(*map(get_async, urls))

ถ้าคุณต้องการไวยากรณ์การทำงาน, gamla lib จะรวมสิ่งนี้เข้าget_asyncไว้

จากนั้นคุณสามารถทำได้


await gamla.map(gamla.get_async(10), ["http://google.com", "http://wikipedia.org"])

10คือหมดเวลาในไม่กี่วินาที

(ข้อจำกัดความรับผิดชอบ: ฉันเป็นผู้เขียน)


และrespxสำหรับการเยาะเย้ย / การทดสอบ :)
rlat

0

ฉันได้ลองบางสิ่งโดยใช้วิธีการแบบอะซิงโครนัสในงูใหญ่ฉันเคยโชคดีกว่านี้มาก่อนโดยใช้การบิดสำหรับการเขียนโปรแกรมแบบอะซิงโครนัส มันมีปัญหาน้อยลงและมีการบันทึกไว้อย่างดี นี่คือลิงค์ของสิ่งที่คล้ายกันกับสิ่งที่คุณพยายามบิด

http://pythonquirks.blogspot.com/2011/04/twisted-asynchronous-http-request.html


บิดเป็นแบบเก่า ใช้ HTTPX แทน
AmirHossein

0

โชคไม่ดีเท่าที่ฉันรู้ห้องสมุดการร้องขอไม่ได้มีไว้สำหรับดำเนินการตามคำขอแบบอะซิงโครนัส คุณสามารถasync/awaitล้อมรอบไวยากรณ์ได้requestsแต่จะทำให้คำร้องขอพื้นฐานไม่ซิงโครนัสน้อยลง หากคุณต้องการคำขอ async จริงคุณต้องใช้เครื่องมืออื่น ๆ ที่ให้มา วิธีแก้ปัญหาหนึ่งอย่างคือaiohttp(Python 3.5.3+) มันทำงานได้ดีในประสบการณ์ของฉันใช้กับasync/awaitไวยากรณ์Python 3.7 ด้านล่างฉันเขียนการใช้งานสามอย่างของการดำเนินการคำขอทางเว็บโดยใช้

  1. คำร้องขอแบบซิงโครนัส ( sync_requests_get_all) โดยใช้requestsไลบรารีPython
  2. คำขอแบบซิงโครนัส ( async_requests_get_all) โดยใช้requestsไลบรารีPython ที่หุ้มด้วย Python 3.7 async/awaitและasyncio
  3. การใช้งานแบบอะซิงโครนัสอย่างแท้จริง ( async_aiohttp_get_all) ด้วยaiohttpไลบรารีPython ที่หุ้มด้วยasync/awaitไวยากรณ์Python 3.7 และasyncio
import time
import asyncio
import requests
import aiohttp

from types import SimpleNamespace

durations = []


def timed(func):
    """
    records approximate durations of function calls
    """
    def wrapper(*args, **kwargs):
        start = time.time()
        print(f'{func.__name__:<30} started')
        result = func(*args, **kwargs)
        duration = f'{func.__name__:<30} finsished in {time.time() - start:.2f} seconds'
        print(duration)
        durations.append(duration)
        return result
    return wrapper


async def fetch(url, session):
    """
    asynchronous get request
    """
    async with session.get(url) as response:
        response_json = await response.json()
        return SimpleNamespace(**response_json)


async def fetch_many(loop, urls):
    """
    many asynchronous get requests, gathered
    """
    async with aiohttp.ClientSession() as session:
        tasks = [loop.create_task(fetch(url, session)) for url in urls]
        return await asyncio.gather(*tasks)


@timed
def asnyc_aiohttp_get_all(urls):
    """
    performs asynchronous get requests
    """
    loop = asyncio.get_event_loop()
    return loop.run_until_complete(fetch_many(loop, urls))


@timed
def sync_requests_get_all(urls):
    """
    performs synchronous get requests
    """
    # use session to reduce network overhead
    session = requests.Session()
    return [SimpleNamespace(**session.get(url).json()) for url in urls]


@timed
def async_requests_get_all(urls):
    """
    asynchronous wrapper around synchronous requests
    """
    loop = asyncio.get_event_loop()
    # use session to reduce network overhead
    session = requests.Session()

    async def async_get(url):
        return session.get(url)

    async_tasks = [loop.create_task(async_get(url)) for url in urls]
    return loop.run_until_complete(asyncio.gather(*async_tasks))


if __name__ == '__main__':
    # this endpoint takes ~3 seconds to respond,
    # so a purely synchronous implementation should take
    # little more than 30 seconds and a purely asynchronous
    # implementation should take little more than 3 seconds.
    urls = ['https://postman-echo.com/delay/3']*10

    sync_requests_get_all(urls)
    async_requests_get_all(urls)
    asnyc_aiohttp_get_all(urls)
    print('----------------------')
    [print(duration) for duration in durations]

บนเครื่องของฉันนี่คือผลลัพธ์:

sync_requests_get_all          started
sync_requests_get_all          finsished in 30.92 seconds
async_requests_get_all         started
async_requests_get_all         finsished in 30.87 seconds
asnyc_aiohttp_get_all          started
asnyc_aiohttp_get_all          finsished in 3.22 seconds
----------------------
sync_requests_get_all          finsished in 30.92 seconds
async_requests_get_all         finsished in 30.87 seconds
asnyc_aiohttp_get_all          finsished in 3.22 seconds
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.