code: def async_thread(sol, args, node_attr, node_id, *a, **kw):
      executor = _get_executor(_executor_name(kw.get('executor', False), sol.dsp))
      if not executor:
          return sol._evaluate_node(args, node_attr, node_id, *a, **kw)
      futures = args
      if node_attr['type'] == 'data' and (
              node_attr['wait_inputs'] or 'function' in node_attr):
          futures = args[0].values()
      from concurrent.futures import Future
      futures = {v for v in futures if isinstance(v, Future)}
      def _submit():
          return executor.thread(
              _async_eval, sol, args, node_attr, node_id, *a, **kw
          )
      if futures:
          result = Future()
          def _set_res(fut):
              try:
                  result.set_result(fut.result())
              except BaseException as ex:
                  result.set_exception(ex)
          def _submit_task(fut=None):
              futures.discard(fut)
              not futures and _submit().add_done_callback(_set_res)
          for f in list(futures):
              f.add_done_callback(_submit_task)
      else:
          result = _submit()
      timeout = node_attr.get('await_result', False)
      if timeout is not False:
          return _await_result(result, timeout, sol, node_id)
      n = len(node_attr.get('outputs', []))
      return AsyncList(future=result, n=n) if n > 1 else result