Function: async-start

async-start is a natively compiled function defined in async.el.

Signature

(async-start START-FUNC &optional FINISH-FUNC)

Documentation

Execute START-FUNC (often a lambda) in a subordinate Emacs process.

When done, the return value is passed to FINISH-FUNC. Example:

    (async-start
       ;; What to do in the child process
       (lambda ()
         (message "This is a test")
         (sleep-for 3)
         222)

       ;; What to do when it finishes
       (lambda (result)
         (message "Async process done, result should be 222: %s"
                  result)))

If you call async-send from a child process, the message will be also passed to the FINISH-FUNC. You can test RESULT to see if it is a message by using async-message-p. If nil, it means this is the final result. Example of the FINISH-FUNC:

    (lambda (result)
      (if (async-message-p result)
          (message "Received a message from child process: %s" result)
        (message "Async process done, result: %s" result)))

If FINISH-FUNC is nil or missing, a future is returned that can be inspected using async-get, blocking until the value is ready. Example:

    (let ((proc (async-start
                   ;; What to do in the child process
                   (lambda ()
                     (message "This is a test")
                     (sleep-for 3)
                     222))))

        (message "I'm going to do some work here") ;; ....

        (message "Waiting on async process, result should be 222: %s"
                 (async-get proc)))

If you don't want to use a callback, and you don't care about any return value from the child process, pass the ignore symbol as the second argument (if you don't, and never call async-get, it will leave *emacs* process buffers hanging around):

    (async-start
     (lambda ()
       (delete-file "a remote file on a slow link" nil))
     'ignore)

Special case: If the output of START-FUNC is a string with properties e.g. (buffer-string) RESULT will be transformed in a list where the car is the string itself (without props) and the cdr the rest of properties, this allows using in FINISH-FUNC the string without properties and then apply the properties in cdr to this string (if needed). Properties handling special objects like markers are returned as list to allow restoring them later. See <https://github.com/jwiegley/emacs-async/issues/145> for more infos.

Note: Even when FINISH-FUNC is present, a future is still returned except that it yields no value (since the value is passed to FINISH-FUNC). Call async-get on such a future always returns nil. It can still be useful, however, as an argument to async-ready or async-wait.

Source Code

;; Defined in /nix/store/jhxqyr2zk061dl3wd3vm38lw3zin47b9-emacs-packages-deps/share/emacs/site-lisp/elpa/async-20260729.1431/async.el
;;;###autoload
(defun async-start (start-func &optional finish-func)
  "Execute START-FUNC (often a lambda) in a subordinate Emacs process.
When done, the return value is passed to FINISH-FUNC.  Example:

    (async-start
       ;; What to do in the child process
       (lambda ()
         (message \"This is a test\")
         (sleep-for 3)
         222)

       ;; What to do when it finishes
       (lambda (result)
         (message \"Async process done, result should be 222: %s\"
                  result)))

If you call `async-send' from a child process, the message will
be also passed to the FINISH-FUNC.  You can test RESULT to see if
it is a message by using `async-message-p'.  If nil, it means
this is the final result.  Example of the FINISH-FUNC:

    (lambda (result)
      (if (async-message-p result)
          (message \"Received a message from child process: %s\" result)
        (message \"Async process done, result: %s\" result)))

If FINISH-FUNC is nil or missing, a future is returned that can
be inspected using `async-get', blocking until the value is
ready.  Example:

    (let ((proc (async-start
                   ;; What to do in the child process
                   (lambda ()
                     (message \"This is a test\")
                     (sleep-for 3)
                     222))))

        (message \"I'm going to do some work here\") ;; ....

        (message \"Waiting on async process, result should be 222: %s\"
                 (async-get proc)))

If you don't want to use a callback, and you don't care about any
return value from the child process, pass the `ignore' symbol as
the second argument (if you don't, and never call `async-get', it
will leave *emacs* process buffers hanging around):

    (async-start
     (lambda ()
       (delete-file \"a remote file on a slow link\" nil))
     \\='ignore)

Special case:
If the output of START-FUNC is a string with properties
e.g. (buffer-string) RESULT will be transformed in a list where the
car is the string itself (without props) and the cdr the rest of
properties, this allows using in FINISH-FUNC the string without
properties and then apply the properties in cdr to this string (if
needed).
Properties handling special objects like markers are returned as
list to allow restoring them later.
See <https://github.com/jwiegley/emacs-async/issues/145> for more infos.

Note: Even when FINISH-FUNC is present, a future is still
returned except that it yields no value (since the value is
passed to FINISH-FUNC).  Call `async-get' on such a future always
returns nil.  It can still be useful, however, as an argument to
`async-ready' or `async-wait'."
  (let ((sexp start-func)
        ;; Subordinate Emacs will send text encoded in utf-8-emacs-unix.
        (coding-system-for-read 'utf-8-emacs-unix))
    (setq async--procvar
          (apply 'async-start-process
                 "emacs" (file-truename
                          (expand-file-name invocation-name
                                            invocation-directory))
                 finish-func
                 (async--emacs-program-args (if (not async-send-over-pipe) sexp))))

    (if async-send-over-pipe
        (async--transmit-sexp async--procvar (list 'quote sexp)))
    async--procvar))