sav*_*ior 5 emacs asynchronous
我使用异步来调用elisp中的异步函数.
首先,我在github上测试自述文件代码并且运行良好.
然后我写了一个测试代码:
(defun async-function ()
(async-start
;; What to do in the child process
(lambda ()
(shell-command-to-string "~/test.sh"))
;; What to do when it finishes
(lambda (result)
(message "Async process done, result is: %s" result)))
Run Code Online (Sandbox Code Playgroud)
test.sh代码非常简单:
#! /usr/bin/env sh
sleep 2
echo "shell finish"
Run Code Online (Sandbox Code Playgroud)
它可以工作,但是当我改变这样的lisp代码时失败了:
;;;###autoload
(defun test ()
(shell-command-to-string "~/test.sh"))
(defun async-function ()
(async-start
;; What to do in the child process
(lambda ()
(test))
;; What to do when it finishes
(lambda (result)
(message "Async process done, result is: %s" result)))
Run Code Online (Sandbox Code Playgroud)
结果是:
error in process sentinel: Symbol's function definition is void: test
Run Code Online (Sandbox Code Playgroud)
我使用该autoload函数加载函数文件,但结果告诉我找不到该文件.
我不知道发生了什么以及如何解决.
Jor*_*ndo 14
async.el的工作原理是生成另一个用于评估表达式的Emacs进程.在这种情况下,您可以在主Emacs进程中定义测试功能,但异步Emacs进程无法访问主进程中的函数和变量.如果要指定要使用的异步调用的函数,请将它们放在文件中并将该文件加载到异步函数中.但请记住,变量等不会转移.
这是一个例子,这是一个文件:
;; ~/.emacs.d/my-functions.el
(defun test ()
(sit-for 2)
"Hello, World!.")
Run Code Online (Sandbox Code Playgroud)
这是在其他地方:
;; somewhere else
(async-start
(lambda ()
(load-file "~/.emacs.d/my-functions.el")
(test))
(lambda (result)
(message "result: %s" result))) ;; will message hello world
Run Code Online (Sandbox Code Playgroud)
关于共享变量,async不支持此功能.您不能做的是启动一个异步函数,该函数不断修改变量并期望在主emacs进程中访问它,或者甚至只是将变量传递给异步lambda,因为该符号在它打开之前不会被计算它不存在的新过程.
我们可以利用Lisp的反引号语法将我们的变量按值传递给异步函数.下面是在异步函数中使用局部变量和函数的非常hacky方法.
;; We will declare a local variable `myvar'
(setq myvar "Bob")
;; Here is a simple function, notice that it does not
;; refer to other non standard functions or other local variables
(defun hello (name)
(format "Hello, %s!" name))
(defun my-async-function ()
(async-start
;; notice the backquote!
`(lambda ()
;; in our async lambda we dont use the local `myvar' variable,
;; instead we are replacing it with the current local value of `myvar'
(set 'myvar ,myvar)
;; we can also do this by actually obtaining the lambda expression
;; behind `hello' and putting that inside our lambda
(fset 'hello ,(symbol-function 'hello))
;; then we wait!
(sit-for 1)
;; now we are modifiying the async copy of `myvar'
(setq myvar (concat myvar " Johnson"))
;; here we want the result of the async lambda to be a call to our
;; `hello' function, but we also want to update our local version
;; of myvar with its value in th async process, so we will return
;; a list of both values which we can handle in our callback
(list myvar (hello myvar)))
(lambda (result)
;; once we get the results we'll update our local version of `myvar'
;; with the value returned by the async function
(setq myvar (first result))
;; then we can print out the message we recieved from the output
;; of our async `hello' call.
(message "The new value myvar is: %s\nThe result of the function was: %s"
myvar
(second result)))))
;; executed top down, the async callback will message:
;;The new value myvar is: Bob Johnson
;;The result of the function was: Hello, Bob Johnson!
Run Code Online (Sandbox Code Playgroud)
我已经用一个宏来抽象出用直接值替换变量和函数的概念:value-bound-lambda,你可以得到宏并在这里看一个例子:
| 归档时间: |
|
| 查看次数: |
1043 次 |
| 最近记录: |