2017-04-09 5 views
0

아래 예제를 사용하여 Asyn인지 여부를 확인했습니다. 그러나 그것은 작동하지 않는 것 같습니다. 아래 코드를 사용했습니다.Python asyncio-motor가 비동기식으로 작동하지 않음

import asyncio 
import time 
from motor.motor_asyncio import AsyncIOMotorClient 


async def get_all_from_coll(col): 
    client = AsyncIOMotorClient("localhost", 27017) 
    db = client.project_matrix 
    cursor = db[col].find() 
    time.sleep(5) 
    for document in await cursor.to_list(length=100): 
     print(document) 


loop = asyncio.get_event_loop() 
print('001') 
loop.run_until_complete(get_all_from_coll('users')) 
print('002') 
내가
>>>001 
>>>{'_id': ObjectId('58d9b178d011b53743d44413'), 'username': 'test1', 'password': 'test', '__v': 0} 
>>>{'_id': ObjectId('58d9b229d011b53743d44414'), 'username': 'test2', 'password': 'test', '__v': 0} 
>>>002 

내가 뭔가 잘못하고 있는가 위해 아래에 출력을 얻고있다

?

+0

'time.sleep'이 (가) 차단 중입니다. 대신에'asyncio.sleep'을 사용하십시오. – dirn

답변

1
for document in await cursor.to_list(length=100): 
    # (wrong) 

이것은 for 루프를 시작하기 전에 완료 cursor.to_list() 기다립니다. 비동기 for 루프를 실행하려면 (한 문서에서-A-시간), you should use an async for :


그러나 이후

async for document in cursor.limit(100): 
    # (ok) 
당신의 print("002") loop.run_until_complete을 실행됩니다, 나는 어떤 문제를 볼 수 없습니다 당신의 출력 순서.

+0

자바 스크립트와 같은 언어로이 작업을 수행 한 경우 결과는 입니다. >>> 001 >>> 002 >>> { '_ id': ObjectId ('58d9b178d011b53743d44413'), 'username': 'test1', 'password ','test ','test ','test ','__v ': 0} >>> {'id ': ObjectId ('58d9b229d011b53743d44414 '),'사용자 이름 ':'테스트 2 ','비밀번호 ':'테스트 ','__v ' 나는 그것을 얻지 않는다. 순서가 아닌 경우 비동기라면 차이점은 무엇입니까? – CoderS

+0

@CoderS'loop.run_until_complete'은 태스크가 완료 될 때까지 기다릴 것이라는 것을 의미합니다. 메인 "thread"는'get_all_from_coll' "thread"에서 차단됩니다. 따라서 본질적으로 프로그램은 단일 스레드가됩니다. – kennytm

+0

그래서 get_all_from_coll을 비동기 적으로 실행할 때 장점이 없습니까? – CoderS

0

async for을 사용하거나 await cursor.to_list()을 사용하면 문제가되지 않습니다. 두 경우 모두 하나 이상의 블록이 있습니다. await 커서가 사용되는 경우에는 한 번만 차단하고 async for는 여러 블록을 가질 수 있습니다.

관련 문제