回答編集履歴

3

ensure_futureについて追記

2021/06/21 03:26

投稿

退会済みユーザー
test CHANGED
@@ -238,9 +238,9 @@
238
238
 
239
239
  ]
240
240
 
241
-
241
+ # 注)python 3.7より前のバージョンだとcreate_taskが使えません。その場合は代わりに「ensure_future」を使います。
242
-
242
+
243
- for data in asyncio.as_completed([asyncio.ensure_future(coro) for coro in coros]):
243
+ for data in asyncio.as_completed([asyncio.create_task(coro) for coro in coros]):
244
244
 
245
245
  res = await data
246
246
 

2

変数名の修正

2021/06/21 03:26

投稿

退会済みユーザー
test CHANGED
@@ -206,9 +206,9 @@
206
206
 
207
207
  # get_data1を短縮したもの。
208
208
 
209
- coros = [("A", 2),("B", 1),("C", 3),("D", 1),("E", 4)]
209
+ args = [("A", 2),("B", 1),("C", 3),("D", 1),("E", 4)]
210
-
210
+
211
- results = await asyncio.gather(*[async_get_data(*coro) for coro in coros])
211
+ results = await asyncio.gather(*[async_get_data(*arg) for arg in args])
212
212
 
213
213
  print(results)
214
214
 

1

追加

2021/06/21 02:15

投稿

退会済みユーザー
test CHANGED
@@ -119,3 +119,133 @@
119
119
 
120
120
 
121
121
  get_data()コルーチンはFlaskによって自動的にイベントループに割り当てられて駆動されるため、その内部でloop.run_until_completeを呼び出すことはできません。
122
+
123
+
124
+
125
+
126
+
127
+ ---
128
+
129
+ # 追記
130
+
131
+ (編集後の追加質問について)
132
+
133
+ > また、非同期処理で4秒以内にすべての処理がおわるように実装したいと思っています。
134
+
135
+
136
+
137
+ いくつかやり方があります。
138
+
139
+ 下記のコードを実行し、/data1 /data2 /data3 と異なるURLにアクセスして挙動を見てみてください。
140
+
141
+
142
+
143
+ /data1 と/data2 は同じ挙動(data2はdata1を短縮した書き方)ですが、
144
+
145
+ /data3は結果を表示するタイミングが/data1、/data2と異なります。
146
+
147
+
148
+
149
+ いずれも4秒以内に処理が完了しています。
150
+
151
+
152
+
153
+ ```
154
+
155
+ from flask import Blueprint, Flask
156
+
157
+ import asyncio
158
+
159
+ import time
160
+
161
+
162
+
163
+ app = Blueprint("app", __name__)
164
+
165
+
166
+
167
+ async def async_get_data(name, sec):
168
+
169
+ print(f"start {name}")
170
+
171
+ await asyncio.sleep(sec)
172
+
173
+ print(f"end {name}")
174
+
175
+ return f"{name}/{sec}"
176
+
177
+
178
+
179
+ @app.route("/data1")
180
+
181
+ async def get_data1():
182
+
183
+ results = await asyncio.gather(
184
+
185
+ async_get_data("A", 2),
186
+
187
+ async_get_data("B", 1),
188
+
189
+ async_get_data("C", 3),
190
+
191
+ async_get_data("D", 1),
192
+
193
+ async_get_data("E", 4)
194
+
195
+ )
196
+
197
+ print(results)
198
+
199
+ return "data1 SUCCESS!"
200
+
201
+
202
+
203
+ @app.route("/data2")
204
+
205
+ async def get_data2():
206
+
207
+ # get_data1を短縮したもの。
208
+
209
+ coros = [("A", 2),("B", 1),("C", 3),("D", 1),("E", 4)]
210
+
211
+ results = await asyncio.gather(*[async_get_data(*coro) for coro in coros])
212
+
213
+ print(results)
214
+
215
+ return "data2 SUCCESS!"
216
+
217
+
218
+
219
+
220
+
221
+ @app.route("/data3")
222
+
223
+ async def get_data3():
224
+
225
+ # コルーチンが完了するごとに結果を取得して表示。
226
+
227
+ coros = [
228
+
229
+ async_get_data("A", 2),
230
+
231
+ async_get_data("B", 1),
232
+
233
+ async_get_data("C", 3),
234
+
235
+ async_get_data("D", 1),
236
+
237
+ async_get_data("E", 4)
238
+
239
+ ]
240
+
241
+
242
+
243
+ for data in asyncio.as_completed([asyncio.ensure_future(coro) for coro in coros]):
244
+
245
+ res = await data
246
+
247
+ print(res)
248
+
249
+ return "data3 SUCCESS!"
250
+
251
+ ```