盘点api问题统一修正 - #2467
盘点api问题统一修正#2467wangxiaokou wants to merge 17 commits into
Conversation
| Keyboard.removeAllListeners('keyboardDidShow') | ||
| Keyboard.removeAllListeners('keyboardDidHide') | ||
| hasListener = false | ||
| return |
hiyuki
left a comment
There was a problem hiding this comment.
本次改动涉及 Web/RN 对外 API 行为,但未同步 docs-vitepress/ 文档;其中 RN storage、window、keyboard、network 行为变化也需要按仓库约束同步 .agents/skills/mpx2rn/。另外当前两组 unit check 均失败,建议补充本次 off/close 行为的核心单测并修复 CI 后再合入。
| if (callbacks.length === 0) { | ||
| if (callbacks.length === 0 || callback == null) { | ||
| callbacks.length = 0 | ||
| Keyboard.removeAllListeners('keyboardDidShow') |
There was a problem hiding this comment.
[P1] 不要清除其他模块注册的 Keyboard 监听
Keyboard.removeAllListeners() 会删除整个 React Native Keyboard emitter 上该事件的全部订阅,包括业务代码和第三方库注册的监听。现在无参 offKeyboardHeightChange() 会稳定触发这个副作用。建议保存本模块两次 Keyboard.addListener() 返回的 subscription,并在此处只调用这些 subscription 的 remove()。
| } | ||
| if (this._closeData) { | ||
| this._closeCb(event) | ||
| this._closeCb(this._closeData) |
There was a problem hiding this comment.
[P2] onClose 应返回底层真实关闭结果
这里用请求关闭时保存的 _closeData 覆盖了真实 CloseEvent。例如调用 close({ code: 1000 }) 后连接在关闭握手期间异常断开,浏览器可能返回 1006,当前实现仍会上报 1000。close() 可以继续把 code/reason 传给底层,但 onclose 应始终根据 event.code 和 event.reason 构造回调参数。
| } | ||
| if (callbackFn == null) { | ||
| // 不传 callback 时清除所有监听 | ||
| fnMap.forEach((proxyCallback, originalCallback) => { |
There was a problem hiding this comment.
[P2] 空参 off 无法移除同一 callback 的重复注册
onNetworkStatusChange 每次都会创建并注册新的 proxyCallback,但 fnMap.set(callbackFn, proxyCallback) 只保留最后一个。同一 callback 注册多次后,这里的遍历只能移除最后一个 wrapper,之前的监听会永久残留,因此没有实现“移除全部”。建议为每个原始 callback 保存全部 wrapper,或重复注册前先移除旧 wrapper。
…o fix-api-proxy-error
hiyuki
left a comment
There was a problem hiding this comment.
发现两个音频事件处理问题,均已通过独立复现测试确认。现有 api-proxy 的 28 个测试套件、110 个测试及变更文件 ESLint 检查通过,但尚未覆盖以下场景。
| ? (e) => { if (!_stopping) cb(e) } | ||
| : cb | ||
| eventCallbacks[nativeName].push({ cb, wrapper }) | ||
| audio.addEventListener(nativeName, wrapper) |
There was a problem hiding this comment.
[P2] 重复注册的暂停监听无法完整注销
连续两次调用 onPause(cb) 会生成两个不同的 wrapper,而 offPause(cb) 只移除第一个匹配项,因此注销后再次派发 pause 事件,cb 仍然会执行一次。旧实现直接把同一个 cb 交给 addEventListener,会由原生事件系统去重,因此这是行为回归。
复现:audio.onPause(cb); audio.onPause(cb); audio.offPause(cb),随后派发原生 pause 事件,预期 cb 不执行,实际执行一次。建议按原始回调去重,或在注销时移除所有匹配项,并补充此场景的测试。
| audio.currentTime = 0 | ||
| setTimeout(() => { | ||
| _stopping = false // pause 事件已经派发完,关掉开关 | ||
| _stopCbs.forEach(cb => cb()) |
There was a problem hiding this comment.
[P2] 停止回调注销自身会导致后续监听漏执行
这里直接遍历 _stopCbs 原数组。如果第一个回调执行 offStop(自身),其中的 splice 会使第二个回调前移,forEach 随后跳过它,导致仍处于注册状态的第二个监听收不到本次停止通知。
复现:依次注册 const first = () => audio.offStop(first) 和另一个回调 second,调用 stop 并执行定时器后,second 实际执行 0 次,预期为 1 次。建议遍历回调数组快照,并补充回调执行过程中注销自身的测试。
location/index.web.js
socket/SocketTask.js
socket/index.web.js
set-navigation-bar/index.web.js
querySelector 查找已有标签,不存在时才创建
create-intersection-observer/IntersectionObserver.js
this._isInit
system/index.ios.js
原来部分 off 方法不传 callback 时行为不一致或无效,统一对齐微信规范(不传 = 移除全部):
涉及文件:app/index.web.js 补全了
offUnhandledRejection、offError、offAppShow、offAppHide、offLazyLoadError;window/index.web.js 和 rnWindow.js 补全了 web
和 RN 两端的 offWindowResize;keyboard/index.ios.js 补全了
offKeyboardHeightChange;device/network/onNetworkStatusChange.js 补全了 web 端的
offNetworkStatusChange,同时修复了单个移除时遗漏 fnMap.delete 的问题;rnNetwork.js 将 RN 端 offNetworkStatusChange
的空参判断从 === undefined 改为 == null,与 null 传参场景对齐。
原实现用单个 audio.cb 属性共享所有事件回调,多次注册会互相覆盖,且 offXxx 逻辑基本失效。重写为:
原来直接调用异步方法(AsyncStorage.removeItem/clear),同步语义完全错误;修正为 envError 占位,明确告知不支持