请教关于有道词典异步获取的问题
EvanMeek opened this issue · 12 comments
作者您好,我正在使用您开发的有道词典插件,功能非常好用。我现在有一个个人计划,现有一个生词表,通过org-capture捕获光标下的单词,并且通过您的youdao-dictionary进行翻译,将一些有用的信息插入到生词表中(例如english,词性,中文)。目前我已经可以正确获取我所需要的信息,但是在使用org-capture是出现了问题,问题如下:
我猜测可能是因为youdao-dictionary是异步请求的,所以在capture获取时没有立即获取到就返回了错误的信息。
下面是我的capture模板
下面是我获取对应信息的函数
由于我个人水平有限,请教下您如何在capture时做一个小延迟,让youdao-dictionary有返回值后再获取捕获的结果
(youdao-dictionary--request WORD &optional CALLBACK)
在没提供 CALLBACK 时是同步的,不是异步的:
(youdao-dictionary--request "hello")
;; => ((translation . ["你好"]) (basic (us-phonetic . "helˈō") (phonetic . "həˈləʊ") (uk-phonetic . "həˈləʊ") (explains . ["int. 喂;哈罗,你好,您好" "n. 表示问候, 惊奇或唤起注意时的用语" "n. (Hello) 人名;(法)埃洛"])) (query . "hello") (errorCode . 0) (web . [(... ...) (... ...) (... ...)]))
你得到了 json-unknown-keyword 错误,说明有道服务器返回数据不是合法 json,你查了哪个词能重现这个问题?
;; no 不是合法的 json
(json-read-from-string "no")
;; error-> (json-unknown-keyword "no")
P.S. 你可以用 Markdown 语法贴代码,编辑器右上角有个 <>
Insert Code 的按钮。你的代码没贴全,函数结尾看不到。
P.S. 你可以用 Markdown 语法贴代码,编辑器右上角有个
<>
Insert Code 的按钮。你的代码没贴全,函数结尾看不到。
多谢提醒,下面是函数的定义:
(defun evan/capture-get-word-eng(type)
(interactive "^p")
(let* ((point-word (thing-at-point 'word))
(evan/capture-word-translate (youdao-dictionary--request point-word))
(evan/capture-word-eng point-word)
(evan/capture-word-chinese (cdar (nthcdr 3 (cdadr evan/capture-word-translate))))
(evan/capture-word-type nil))
;; 获取单词词性
(progn (string-match "[a-zA-Z]+" (aref evan/capture-word-chinese 0)) ;; 匹配英文字符
;; 设置词性 格式为: "adj."
(setq evan/capture-word-type (concat (match-string 0 (aref evan/capture-word-chinese 0)) ".")))
;; 设置单词中文
(progn (string-match "[\u4e00-\u9fa5;,]+" (aref evan/capture-word-chinese 0))
;; 设置中文
(setq evan/capture-word-chinese (match-string 0 (aref evan/capture-word-chinese 0))))
;; 根据参数返回具体的值
(cond ((eq type 1) evan/capture-word-eng)
((eq type 2) evan/capture-word-type)
((eq type 3) evan/capture-word-chinese))))
我不知道怎么回事,你得到的 json-unknown-error 是哪里来的?你能不能找找具体什么地方出了问题。
(youdao-dictionary--request WORD &optional CALLBACK)
在没提供 CALLBACK 时是同步的,不是异步的:(youdao-dictionary--request "hello") ;; => ((translation . ["你好"]) (basic (us-phonetic . "helˈō") (phonetic . "həˈləʊ") (uk-phonetic . "həˈləʊ") (explains . ["int. 喂;哈罗,你好,您好" "n. 表示问候, 惊奇或唤起注意时的用语" "n. (Hello) 人名;(法)埃洛"])) (query . "hello") (errorCode . 0) (web . [(... ...) (... ...) (... ...)]))你得到了 json-unknown-keyword 错误,说明有道服务器返回数据不是合法 json,你查了哪个词能重现这个问题?
;; no 不是合法的 json (json-read-from-string "no") ;; error-> (json-unknown-keyword "no")
前面我用的是老版本的youdao-dictionary,现在已经更新了,能看到callback参数了。
不过仍然会有json-unknow-error问题(单独调用youdao-dictionary--request是没问题的),是不是因为capture模板那边调用我的函数时就立即返回了,没有等待数据。。。
刚刚又测试了一下,我发现好像是因为光标下没有单词所以point-word永远为nil,因为我是先呼出capture,然后再通过capture的模板调用函数的,所以光标下的单词永远为空..
噢,原来如此,缺少参数时候返回的不是 json:
$ curl 'http://fanyi.youdao.com/openapi.do?keyfrom=YouDaoCV&key=659600698&type=data&doctype=json&version=1.1&q='
no query
因为 youdao-dictionary--request 没检查参数,你需要自己检查。
而且这个 API 比较简单,你可以自己发送请求,这样就不用我这个包了,比如:
(defun your-youdao (word)
(with-current-buffer
(url-retrieve-synchronously
(concat "http://fanyi.youdao.com/openapi.do?keyfrom=YouDaoCV&key=659600698&type=data&doctype=json&version=1.1&q="
(url-hexify-string word)))
(goto-char url-http-end-of-headers)
(json-read)))
而且你的 Org Capture 模版同一个词发送了三次请求,应该避免,发送一次就够了。
而且你的 Org Capture 模版同一个词发送了三次请求,应该避免,发送一次就够了。
而且你的 Org Capture 模版同一个词发送了三次请求,应该避免,发送一次就够了。
不小心点错了,把issue关闭了。。
我想着youdao-dictionary不是有个缓存嘛,相同的单词会直接从缓存里拿。
噢,原来如此,缺少参数时候返回的不是 json:
$ curl 'http://fanyi.youdao.com/openapi.do?keyfrom=YouDaoCV&key=659600698&type=data&doctype=json&version=1.1&q=' no query
因为 youdao-dictionary--request 没检查参数,你需要自己检查。
而且这个 API 比较简单,你可以自己发送请求,这样就不用我这个包了,比如:
(defun your-youdao (word) (with-current-buffer (url-retrieve-synchronously (concat "http://fanyi.youdao.com/openapi.do?keyfrom=YouDaoCV&key=659600698&type=data&doctype=json&version=1.1&q=" (url-hexify-string word))) (goto-char url-http-end-of-headers) (json-read)))
多谢
你的问题应该解决了,我关闭此 issue 了。