You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pharo技术问询:如何将块/定时任务块内变量返回至方法

在Pharo中处理异步任务里的变量传递

这个问题的核心在于TaskScheduler的任务是异步执行的——你的updateMethod会在启动调度器后立刻完成并返回,而那个每隔60秒跑一次的块是在后台单独执行的。所以没法让方法直接“返回”每次的data,而是需要换一种方式来处理每次生成的data。下面给你几种实用的实现思路:


1. 用实例变量存储最新数据

如果只是需要随时获取最新的data值,可以把data从方法的临时变量改成类的实例变量,这样每次任务块执行时都会更新这个变量,其他地方可以随时读取:

首先给你的类添加实例变量data,并生成访问器方法:

Class>>data
    ^ data ifNil: [ data := Dictionary new ] "给个默认空字典,避免nil报错"

Class>>data: aJsonObject
    data := aJsonObject

然后修改updateMethod:

Class>>updateMethod
"This is a method"
| scheduler |
scheduler := TaskScheduler new.
scheduler start.
"refresh every 60 seconds"
scheduler do: [ | client response |
    client := ZnClient new.
    response := client get: 'https://MyServer/json'.
    Transcript show: 'Refreshing......'; cr.
    self data: (NeoJSONReader fromString: response) ] "更新实例变量"
every: 60 seconds

之后你就可以通过yourClassInstance data随时获取最新的JSON数据了。


2. 传入回调块处理每次数据

如果每次获取到data后需要立刻执行特定逻辑(比如更新UI、存储到本地),可以把处理逻辑做成回调块传给方法:

Class>>updateMethodWithCallback: processingBlock
"This method takes a block to handle each new data batch"
| scheduler |
scheduler := TaskScheduler new.
scheduler start.
scheduler do: [ | client response jsonData |
    client := ZnClient new.
    response := client get: 'https://MyServer/json'.
    Transcript show: 'Refreshing......'; cr.
    jsonData := NeoJSONReader fromString: response.
    processingBlock value: jsonData ] "执行回调处理数据"
every: 60 seconds

使用的时候直接传入处理逻辑:

yourInstance updateMethodWithCallback: [ :newData |
    "这里写你要做的事情,比如打印到Transcript或者更新界面"
    Transcript show: 'New data received: ', newData printString; cr.
]

3. 用Announcement发布数据更新通知

如果你的代码需要解耦——比如多个对象都需要知道数据更新了,Pharo的Announcement系统是个很好的选择:

首先定义一个自定义通知类:

DataUpdatedAnnouncement subclass: #DataRefreshedAnnouncement
    instanceVariableNames: 'data'
    classVariableNames: ''
    package: 'YourPackageName'

DataRefreshedAnnouncement>>data
    ^ data

DataRefreshedAnnouncement>>data: anObject
    data := anObject

然后修改updateMethod来发布通知:

Class>>updateMethod
"This is a method"
| scheduler |
scheduler := TaskScheduler new.
scheduler start.
scheduler do: [ | client response jsonData |
    client := ZnClient new.
    response := client get: 'https://MyServer/json'.
    Transcript show: 'Refreshing......'; cr.
    jsonData := NeoJSONReader fromString: response.
    "发布数据更新通知"
    DataRefreshedAnnouncement new
        data: jsonData;
        announce ]
every: 60 seconds

最后在需要接收数据的对象里订阅通知:

"在你的UI类或者其他处理类里"
self when: DataRefreshedAnnouncement do: [ :announcement |
    | latestData |
    latestData := announcement data.
    "处理最新数据"
    Transcript show: 'Received updated data: ', latestData printString; cr.
]

顺便提下原代码的小问题:

  • 原代码里a get: 'https://MyServer/json'的a没有定义,需要创建ZnClient实例来发起请求;
  • NeoJSONReader fromString: a contents; cr.语法错误,分号用于同一接收者的消息链,这里应该分开写,而且ZnClient的get:方法直接返回响应内容,不需要再取contents。

内容的提问来源于stack exchange,提问作者ludo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:27:24