Короткий ответ: вам нужно выполнить обратный вызов следующим образом:
function callback(response) {
// Here you can do what ever you want with the response object.
console.log(response);
}
$.ajax({
url: "...",
success: callback
});
Проблема в том, что привязки переменных Emacs Lisp по умолчанию динамические. То есть, когда функция оценивается, связанные переменные просматриваются не в среде, где была определена функция, но в среде, где была вызвана функция.
Emacs 24 или позже поддерживает лексическую привязку (т. е. функция видит переменные, которые были связаны вокруг определения функции ) изначально, но поскольку она изменяет семантику существующего кода, вам необходимо явно ее включить. Обычно это делается путем добавления локальной переменной файла в первую строку файла .el
:
;; -*- lexical-binding: t; -*-
Другой альтернативой является использование lexical-let
из библиотеки cl
. Это работает и в предыдущих версиях Emacs. Обратите внимание, что таким образом вы явно указываете, какие переменные должны иметь лексическую привязку, поэтому код, такой как (lexical-let ((foo foo)) ...)
, не является редкостью - foo
- это существующая переменная, которая должна быть «перенесена» в функцию.
Хорошо, я думаю, что у меня есть это сейчас. Приведенный выше пример является хорошим примером; вот еще один случай, если у кого-то еще есть такая трудность:
;;; ensure VAR1 has no binding
(makunbound 'VAR1)
;;;
(defun f1 (&optional VAR1)
(interactive)
(unless VAR1
(set 'VAR1 "variable1"))
(pop-to-buffer "*test*")
; (lexical-let ( (VAR1 VAR1) ) ;;;
(set-process-sentinel
(start-process-shell-command "test"
"*test*"
(concat "echo " VAR1))
(lambda (process event)
(condition-case err
(when (string-match-p "finished" event)
(f2 VAR1))
(error
(princ
(format "Sentinel error: %s" err))))))
; ) ;;;
)
;;;
(defun f2 (&optional VAR2)
(interactive)
(unless VAR2
(set 'VAR2 "VARIABLE2"))
(print VAR2))
Мы загружаем все (с комментариями в (f1)
) и запускаем (f1)
. Значение VAR1
передается в (f2)
перед , когда происходит ошибка. Похоже, что ошибка (void-variable VAR1
) исходит из области определения области видимости (set-process sentinel PROCESS SENTINEL)
; VAR1
не определен там, хотя он остается в области функции SENTINEL
((lambda)
).
Также использование (set )
, как указано выше, не является наилучшей практикой, когда переменная предназначена только для того, чтобы область была локальной для функции.
Если мы раскомментируем строки, помеченные знаком ;
, тогда все работает так, как ожидалось. К счастью, мы можем передать значение до другой функции, которая предотвращает создание длинной серии (set-process sentinel )
. Это также позволяет нам генерировать процессы с дополнительными подпроцессами, если это необходимо.
Одна из моих ошибок заключалась в том, что SENTINEL
называлась дискретной функцией, а не удерживала ее внутри функции (lexical-let )
. Хотя подход lexical-binding: t;
привлекателен, он, как правило, нарушает рабочий код, который опирается на стандарт (let )
.
Ниже приведен пример использования динамических привязок:
(defun example-dynamic-fn ()
"Doc-string"
(interactive)
(let ((test-variable "Hello-world!"))
(set-process-sentinel
(start-process "process-one" "*one*" "echo" test-variable)
`(lambda (p e) (when (= 0 (process-exit-status p))
(set-process-sentinel
(start-process "process-two" "*two*" "echo" ,test-variable)
'(lambda (p e) (when (= 0 (process-exit-status p))
(start-process "process-three" "*three*" "echo" ,test-variable)
(set-process-sentinel
(start-process "process-four" "*four*" "echo" ,test-variable)
'(lambda (p e) (when (= 0 (process-exit-status p))
(set-process-sentinel
(start-process "process-five" "*five*" "echo" ,test-variable)
'(lambda (p e) (when (= 0 (process-exit-status p))
(message "test-variable: %s" ,test-variable)))))))))))))))