如何在Reason/BuckleScript的两个事件处理器间共享数据?
在Reason/BuckleScript中处理http.get回调的可变状态问题
你遇到的核心问题是Reason的不可变绑定特性:let results = []创建的是一个不可变的数组绑定,你无法在回调里直接重新赋值(results = [data, ...results])——因为每次赋值都会创建一个新的局部绑定,而end回调无法访问这个新绑定。
下面是两种常用的解决方案,完美对应你要实现的Node.js功能:
方案1:使用可变数组(贴近Node.js原生写法)
BuckleScript提供了Js.Array模块来操作Node.js风格的可变数组,和你熟悉的JS数组用法一致:
Http.Client.get("http://jsonplaceholder.typicode.com/posts/1", response => { // 创建一个空的可变数组 let results = Js.Array.make(); Http.IncomingMessage.on( response, `data(data => { // 直接往可变数组里追加chunk Js.Array.push(results, data); }), ); Http.IncomingMessage.on( response, `_end(() => { // 拼接数组内容并打印 let combinedContent = Js.Array.joinWith("", results); Js.log(combinedContent); }), ); });
方案2:使用Ref引用(函数式风格的可变状态)
如果你更倾向于保持数组的不可变性,同时需要在回调间共享状态,可以使用Reason的ref引用(本质是一个可变的容器,用来存放不可变数据):
Http.Client.get("http://jsonplaceholder.typicode.com/posts/1", response => { // 创建一个引用,初始值为空数组 let resultsRef = ref([]); Http.IncomingMessage.on( response, `data(data => { // 更新引用里的数组(生成新的不可变数组,替换引用内容) resultsRef := [data, ...resultsRef^]; }), ); Http.IncomingMessage.on( response, `_end(() => { // 取出引用中的数组并拼接 let combinedContent = Js.Array.joinWith("", resultsRef^); Js.log(combinedContent); }), ); });
两种方案的选择
- 如果你习惯Node.js的原生写法,可变数组更直观,代码和你原来的JS版本最接近;
- 如果你希望遵循函数式编程的不可变原则,Ref引用是更地道的Reason写法,适合需要跟踪不可变状态变化的场景。
两种方案都能完美实现你要的功能:累积data回调的chunk,在end回调里拼接并打印。
内容的提问来源于stack exchange,提问作者ThomasThiebaud
相关产品推荐
相关产品推荐

