向Session注册一个回调函数,返回回调id :type callback: Callable or Coroutine :param callback: 回调函数. 函数签名为 ``callback(data)``. ``data`` 参数为回调事件的值 :param bool mutex_mode: 互斥模式。若为 ``True`` ,则在运行回调函数过程中,无法响应同一组件(callback_id相同)的新点击事件,仅当 ``callback`` 为协程函数时有效 :return str: 回调id.
(self, callback, mutex_mode=False)
| 171 | self._cleanup() |
| 172 | |
| 173 | def register_callback(self, callback, mutex_mode=False): |
| 174 | """ 向Session注册一个回调函数,返回回调id |
| 175 | |
| 176 | :type callback: Callable or Coroutine |
| 177 | :param callback: 回调函数. 函数签名为 ``callback(data)``. ``data`` 参数为回调事件的值 |
| 178 | :param bool mutex_mode: 互斥模式。若为 ``True`` ,则在运行回调函数过程中,无法响应同一组件(callback_id相同)的新点击事件,仅当 ``callback`` 为协程函数时有效 |
| 179 | :return str: 回调id. |
| 180 | """ |
| 181 | |
| 182 | async def callback_coro(): |
| 183 | while True: |
| 184 | try: |
| 185 | event = await self.next_client_event() |
| 186 | except SessionClosedException: |
| 187 | return |
| 188 | |
| 189 | assert event['event'] == 'callback' |
| 190 | coro = None |
| 191 | if iscoroutinefunction(callback): |
| 192 | coro = callback(event['data']) |
| 193 | elif isgeneratorfunction(callback): |
| 194 | coro = asyncio.coroutine(callback)(event['data']) |
| 195 | else: |
| 196 | try: |
| 197 | res = callback(event['data']) |
| 198 | if asyncio.iscoroutine(res): |
| 199 | coro = res |
| 200 | else: |
| 201 | del res # `res` maybe pywebio.io_ctrl.Output, so need release `res` |
| 202 | except Exception: |
| 203 | self.on_task_exception() |
| 204 | |
| 205 | if coro is not None: |
| 206 | if mutex_mode: |
| 207 | await coro |
| 208 | else: |
| 209 | self.run_async(coro) |
| 210 | |
| 211 | cls = type(self) |
| 212 | callback_task = Task(callback_coro(), cls.get_current_session()) |
| 213 | # Activate task |
| 214 | # Don't callback.step(), it will result in recursive calls to step() |
| 215 | # todo: integrate with inactive_coro_instances |
| 216 | callback_task.coro.send(None) |
| 217 | cls.get_current_session().coros[callback_task.coro_id] = callback_task |
| 218 | |
| 219 | self._need_keep_alive = True |
| 220 | |
| 221 | return callback_task.coro_id |
| 222 | |
| 223 | def run_async(self, coro_obj): |
| 224 | """异步运行协程对象。可以在协程内调用 PyWebIO 交互函数 |
nothing calls this directly
no test coverage detected