4

文档说with-timeout宏只能等待它在内部执行的代码“是可以等待的原语”。有没有这种原始的例子?

更多信息:我遇到了一种情况,我必须从一个对 TCP 服务器进行异步调用的函数返回结果。因此,如果您知道如何使此调用同步,那也会有所帮助。

不幸的是,我不能选择让它同步——这是一个由自动完成库调用的回调,它必须返回值。以下是尝试执行此操作的代码:

(defun haxe-ac-init ()
  (unless (get-process haxe-compiler-process)
    (haxe-connector-sentinel nil nil))
  (let ((ac-request
         (haxe-build-compile-string
          (haxe-package) (buffer-file-name))))
    (save-buffer)
    (setq haxe-last-ac-candidates nil)
    (process-send-string haxe-compiler-process ac-request)
    (process-send-string haxe-compiler-process "\0")
    (process-send-eof haxe-compiler-process))
  (haxe-log 3 "haxe-ac-init sent request.")
  (with-local-quit
    (with-timeout (3 (haxe-log 0 "Compiler is too slow..."))
      (block x ;; this while sometimes will loop forever
        (while (equal (process-status (get-process haxe-compiler-process)) 'open)
          (when (and last-compiler-response (= received-status 2))
            (haxe-parse-ac-response last-compiler-response)
            (throw 'x haxe-last-ac-candidates)))))))
4

1 回答 1

2

要回答我自己的问题,这并不容易!:) 所以...为了使with-timeout工作,就我而言,我必须accept-process-output进入循环。这似乎使 Emacs 有能力中断循环,从等待写入的进程中读取并返回到循环。最终版本的代码如下:

(defun haxe-ac-init ()
  (message "haxe-ac-init 0 %s" (get-process haxe-compiler-process))
  (let ((old-proc (get-process haxe-compiler-process)))
    ;; (message "haxe-ac-init 1 %s %s" old-proc (when old-proc (process-status old-proc)))
    ;; process-live-p doesn't exist :/
    (when (or (not old-proc)
              (not (equal (process-status old-proc) 'open)))
      (setq haxe-network-process nil)
      (haxe-connect-to-compiler-server)
      (sleep-for 1)
      (setq old-proc (get-process haxe-compiler-process)))
    (let ((ac-request
           (haxe-build-compile-string
            (haxe-package) (buffer-file-name))))
      (setq haxe-last-ac-candidates nil
            haxe-last-ac-candidates-filtered nil
            last-compiler-response nil
            received-status 2)
      (clrhash documentation-hash)
      (process-send-string old-proc ac-request)
      (process-send-string old-proc "\0")
      (process-send-eof old-proc)
      (haxe-log 3 "haxe-ac-init sent request: %s\n completing: %s"
                ac-request
                (substring (buffer-string)
                           (max (point-min) (- (point) 10))
                           (point))))
    (with-local-quit
      (with-timeout (5 (haxe-log 0 "Failing to fetch all completion options, giving up"))
        (while (not haxe-last-ac-candidates)
          (accept-process-output old-proc)
          (haxe-log 3 "statsus: %s"
                    (when last-compiler-response
                      (concat
                       (substring last-compiler-response
                                  0 (min (length last-compiler-response) 42)) "...")))
          (when (and last-compiler-response (= received-status 2))
            (if (string= response-terminator "</list>\n")
                (haxe-parse-ac-response last-compiler-response)
              (haxe-parse-hint-response last-compiler-response)))))
      haxe-last-ac-candidates)))
于 2012-06-17T20:24:54.433 回答