javascript - 在 Python 中使用带有 for 循环的 Asyncio,类似于 Javascript 中的 map 方法和 promise.all
问题描述
我正在尝试在 Python 中异步运行 for 循环,就像您可以在 Javascript 中使用 map 方法和 promise.all 一样。我到处搜索如何做到这一点,但下面的代码仍然是同步运行的(一个接一个地运行,而不是让循环在完成之前的迭代时进行其他迭代,比如 promise.all 允许你)。任何帮助,将不胜感激。
from jwt import scopes
from googleapiclient.discovery import build
from google.oauth2 import service_account
import json
import asyncio
key = 'file.json'
ID = 'ID'
rg = 'A1'
j2 = service_account.Credentials.from_service_account_file(key, scopes=scopes).with_subject('me@emial.com')
ar = []
cl = build('classroom', 'v1', credentials=j2)
def cour():
co = []
result1 = cl.courses().list().execute()
courses = result1.get('courses', [])
for cc in courses:
co.append(cc['id'])
return co
cco = cour()
async def main():
async def subs2(i):
await asyncio.sleep(0)
result2 = cl.courses().courseWork().list(courseId=i).execute()
works = result2.get('courseWork', [])
for work in works:
result = cl.courses().courseWork().studentSubmissions().list(courseId=work['courseId'], courseWorkId=work['id']).execute()
subs = result.get('studentSubmissions', [])
for sub in subs:
try:
ar.append(sub['assignedGrade'])
ar.append(sub['courseId'])
ar.append(sub['courseWorkId'])
ar.append(sub['userId'])
except KeyError as name:
pass
coros = [subs2(i) for i in cco]
await asyncio.gather(*coros)
if __name__ == '__main__':
cour()
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
loop.close()
解决方案
我认为您误解了asyncio
提供并发性的方式。它不会产生任何额外的线程或进程。事件循环以及在其上运行的所有协程都在单个线程中执行。为了获得并发性,您的协程需要await
调用执行异步 I/O 或其他一些可以控制异步事件循环的操作。
在您的示例中,您尝试同时运行的协程实际上并没有执行任何异步 I/O。所以每次协程执行时,它都会阻塞事件循环,直到它完成。这意味着每个都将按顺序执行。为了获得并发性,您需要使用对异步友好的库而不是googleapiclient
您当前正在使用的库 ( ),或者使用loop.run_in_executor
.
推荐阅读
- javascript - 我将如何在反应中映射状态渲染?
- xcode - 运行 usdz_converter 但没有任何结果
- android - 多次调用定期请求的工作经理
- php - 无法在 rhel6 上安装 phpmyadmin
- javascript - react antd 大型生产包
- c - 字符串中每个字符的异或总和
- django - 优化使 API 调用的自定义模板标签
- java - 在 Active Directory 轻量级目录服务中使用 java 创建用户
- react-native - Expo React-Native 中不存在 Index.android.js
- sql - 使用临时表时 PySpark 中的 SQL 查询错误