首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用drakma-异步和cl-异步的不可预知的行为

使用drakma-异步和cl-异步的不可预知的行为
EN

Stack Overflow用户
提问于 2014-09-25 07:48:05
回答 1查看 145关注 0票数 4

我正在尝试在我的小项目中使用drakma-async。但我就是不明白发生了什么。(我使用emacs + slime + ccl)。我需要用http(s)获取数据并在回调中解析它。我想我可能会得到不能被解析的错误数据,所以我想重试一次。但当我试着做一些测试时,我就是不明白发生了什么.

代码语言:javascript
复制
(defun my-callback (data)
  (prin1 data)
  (restart-case
      (error "Some error parsing data...")
    (just-continue () (prin1 "Continue..."))))

(defun simple-test ()
  (let ((future (asf:make-future)))
    (as:delay #'(lambda () (asf:finish future "Some data")) :time 2)
    (prin1 (asf:future-finished-p future))
    (asf:attach future #'my-callback)))

(defun drakma-test ()
  (asf:alet ((response (das:http-request "http://www.google.com")))
    ;(prin1 (asf:future-finished-p response))
    (asf:attach response #'my-callback)))

(defun drakma-test-let ()
  (let ((response (das:http-request "http://www.google.com")))
    ;(prin1 (asf:future-finished-p response))
    (asf:attach response #'my-callback)))

(defun run-test (test)
  (as:start-event-loop test))

这就是我的简单例子(这就是我的计划)。

代码语言:javascript
复制
? (run-test #'simple-test)
NIL"Some data"    ;I get debugger here with simple-error and choose my restart
Invoking restart: #<RESTART JUST-CONTINUE #x7F0578EC20AD>
"Continue..."
1

( 2)我在第二次考试中得到的是:

代码语言:javascript
复制
? (run-test #'drakma-test)
"<A LOT OF HTML>
"
1

我的调试器和重新启动在哪里?

3)取消;(prin1 (asf:future...))行在drakma-test中的注释

代码语言:javascript
复制
? (run-test #'drakma-test)
1

没有完成/未完成的bool,没有数据没有打印,我没有得到重新启动,我只是得到1的结果。

4)假设如果编写(let ((reponse (das:http-request "http://www.google.com"))) ... ) instad of (asf:alet ...)response将不包含future对象,但会阻塞,直到请求完成,response将包含数据。

代码语言:javascript
复制
? (run-test #'drakma-test-let)
1

5)取消;(prin1 (asf:future...))行在drakma-test-let中的注释

代码语言:javascript
复制
? (run-test #'drakma-test-let)
NIL   ;future is not finished
1

数据没有打印出来,只是还没有完成和运行测试的结果.

我已经运行了cl-异步的测试,除了ipv6测试之外,它们都通过了。所以我不知道该从哪里开始了解发生了什么.为什么我没有调试器并在第二次测试中重新启动?为什么在第三次测试中什么都不会发生(这与第二次测试相同,但与prin1相同)。为什么在第五次和第五次测试中什么都没有发生?

没有足够的声誉为这个库创建drakma-asynccl-async标记。我知道drakma-async是建立在drakma之上的,所以我放置了这个标签。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-09-29 12:23:02

感谢m-n的评论,使情况变得更清楚,并很快解释了情况。

我做了一些例子,并想说明在每一种情况下发生了什么:

示例:

代码语言:javascript
复制
(defun my-callback (&rest data)
  (format t "Echo from callback: ~A~%" data)
  (restart-case
      (error "Some error parsing data...")
    (just-continue () (prin1 "Continue..."))))

(defun my-errback (e)
  (format t "Echo from errback: ~A~%" e))

(defun make-example-future ()
  (let ((future (asf:make-future))) ;creating future
    (as:delay #'(lambda ()          ;finishing future in 2 seconds
                  (asf:future-handler-case ;wrapping asf:finish
                    (asf:finish future
                                "Result data")
                    (t (e) (asf:signal-error future e)))) ;signal future an error
              :time 2)
    future))

(defun simple-test-2 ()
  (let ((future (make-example-future)))
    (format t "Is future?: ~A~%Finished?: ~A~%"  
            (asf:futurep future) (asf:future-finished-p future))
    (asf:alet ((result future))
      (asf:attach-errback future #'my-errback)
      (format t "Finished? ~A~%" (asf:future-finished-p future))
      (asf:future-finished-p result)
      (asf:attach result #'my-callback))))

下面是正在发生的事情:

代码语言:javascript
复制
? (as:start-event-loop #'simple-test-2)
Is future?: T 
Finished?: NIL
;<here we have a 2 sec pause>
Finished? T
Echo from errback: There is no applicable method for the generic function:
#<STANDARD-GENERIC-FUNCTION CL-ASYNC-FUTURE:FUTURE-FINISHED-P #x302001B67A8F>
when called with arguments:
("Result data")

( A) asf:alet等待结果并将结果值绑定到变量。因此,我错误地认为asf:alet将未来捆绑在一起。

( B)在make-example-future中,我们用asf:future-handler-case封装asf:finish,并使用asf:signal-error向将来发送错误。这意味着将处理错误并调用errback。即使回调被附加在代码的后面。而且,(asf:future-finished-p result)的错误是用future-handler-case处理的,因为它是用asf:alet包装的(至少我认为是这样的)。

( C)对(asf:future-finished-p result)进行注释,结果是

代码语言:javascript
复制
Is future?: T
Finished?: NIL
Finished? T
Echo from callback: (Result data) ;here is my data
Echo from errback: Some error parsing data... ;;here is my error
1

drakma-async中,有类似的包装asf:finishfuture-handler-case包装器。

因此,这解释了#2测试结果。我得到了数据,asf:alet还给了我字符串。回调的错误被传递给了errback,而我没有这个错误。而且。在仅使用drakma-testasf:alet中,我无法附加errback,因为我无法访问未来。我需要打电话给http-requestlet,而不是alet

这也解释了#3测试的结果:我得到了发送给errback(future-finished-p)中的错误。

如果我们使用新的#4#5测试的结果:可以看到,cl-async试图用drakma返回的所有值调用my回调。其中有7个( drakma:http-request返回的值)。因此,我试图附加错误数量的参数回调,我的#4和#5测试发出了一个错误信号,该错误由该future-hander-case处理并发送给errback

结果:无论如何,如果不删除该drakma-async,就不可能使用带有future-handler-case的重新启动,因为它会将错误发送回错,但会丢失所有的重新启动。

如果有人回答我的问题,希望这篇文章能有所帮助。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26033264

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档