@jhh96/light-app-bridge 1.0.5 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +16 -10
- package/dist/lightAppBridge.d.ts +28 -4
- package/dist/lightAppBridge.js +100 -14
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -15,16 +15,15 @@
|
|
|
15
15
|
| `window.worklink`(含 `invokeModuleMethodSync`) | 发送消息 / 取 webContentsId | preload 注入 |
|
|
16
16
|
| `window.worklink.plugin.getContentContext` | 解析目标轻应用 webContentsId(**仅 plugin 角色**) | pluginLightAppPreload 注入 |
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
**收消息(自动选择,不强依赖 waltz):**
|
|
19
19
|
|
|
20
20
|
| 监听后端 | 优先级 | 适用环境 | 说明 |
|
|
21
21
|
|---------|--------|---------|------|
|
|
22
22
|
| `window.waltz.event.on('native-call-js')` | 高(优先) | 有 waltz 注入的环境 | 推荐路径,立即可用 |
|
|
23
|
-
| `window.handleMessageFromNative` | 低(回退) | 无 waltz 的环境 |
|
|
23
|
+
| `window.handleMessageFromNative` | 低(回退) | 无 waltz 的环境 | 由 SDK 定义此全局方法(该方法原本由 waltz.min.js 注册;无 waltz 时为 undefined,renderer 投递消息前会检查其类型,没人定义则消息被丢弃)。renderer 收到消息后主动调用它传入消息。若该方法已存在则包装透传,不破坏原逻辑 |
|
|
24
24
|
|
|
25
|
-
- 两者都始终不可用时,`connect()`/`ready()` reject(构造不抛,因监听后端允许稍后出现)
|
|
26
25
|
- SDK 内部按 waltz → handleMessageFromNative 顺序探测,无需手动指定
|
|
27
|
-
-
|
|
26
|
+
- 握手会等监听绑定后才开始,避免早到的 ack/hello 丢失
|
|
28
27
|
|
|
29
28
|
## 安装(两个项目)
|
|
30
29
|
|
|
@@ -59,14 +58,21 @@ bridge.onMessage((data, id) => {
|
|
|
59
58
|
|
|
60
59
|
```js
|
|
61
60
|
{
|
|
62
|
-
__sdk: '
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
61
|
+
__sdk: 'LightAppBridge', // SDK 标识:过滤出本 SDK 的消息,隔离其它消息
|
|
62
|
+
v: 1, // 协议版本号
|
|
63
|
+
id: 'r_xxx', // 关联 id:send 生成,回复原样带回
|
|
64
|
+
type: 'hello'|'ack'|'req'|'res', // 握手 hello/ack;业务 req/res
|
|
65
|
+
data: any // 任意业务数据
|
|
66
66
|
}
|
|
67
67
|
```
|
|
68
68
|
|
|
69
|
+
## 连接与生命周期
|
|
70
|
+
|
|
71
|
+
- 构造即自动握手(插件发 hello 每秒重试;轻应用持续等待、不超时)
|
|
72
|
+
- 握手失败后**再次 `connect()` 可重连**(自动重置状态,无需重建实例)
|
|
73
|
+
- `destroy()` 销毁实例:解绑监听、拒绝未完成请求;销毁后 `send`/`connect` 立即 reject
|
|
74
|
+
|
|
69
75
|
## 文件
|
|
70
76
|
|
|
71
|
-
- `src/lightAppBridge.
|
|
72
|
-
- `src/index.
|
|
77
|
+
- `src/lightAppBridge.ts` —— SDK 源码(TypeScript,构建产物为 ESM)
|
|
78
|
+
- `src/index.ts` —— barrel re-export
|
package/dist/lightAppBridge.d.ts
CHANGED
|
@@ -39,6 +39,16 @@ export interface BridgeOptions {
|
|
|
39
39
|
timeout?: number;
|
|
40
40
|
/** 握手超时(ms),默认 30000。仅 plugin 角色生效;lightapp 端持续等待,不超时 */
|
|
41
41
|
handshakeTimeout?: number;
|
|
42
|
+
/**
|
|
43
|
+
* 调试模式:开启后在控制台打印完整通信轨迹,便于排查 plugin ↔ lightapp
|
|
44
|
+
* 联调问题。覆盖:
|
|
45
|
+
* - 构造(角色/配置)、握手(hello/ack/连接建立/超时/重连)
|
|
46
|
+
* - 发送请求(send data + id)、底层投递(目标 webContentsId + 信封)
|
|
47
|
+
* - 收到消息(type/id/from/data)、响应返回(res 数据/超时)
|
|
48
|
+
* - handler 异常、销毁
|
|
49
|
+
* 大 payload 截断到 500 字符防刷屏。
|
|
50
|
+
*/
|
|
51
|
+
debug?: boolean;
|
|
42
52
|
}
|
|
43
53
|
/** send 单次调用选项 */
|
|
44
54
|
export interface SendOptions {
|
|
@@ -70,12 +80,18 @@ export default class LightAppBridge {
|
|
|
70
80
|
private _connectPromise;
|
|
71
81
|
private _unlisten;
|
|
72
82
|
private _listenerReady;
|
|
83
|
+
private _connectFailed;
|
|
84
|
+
private _destroyed;
|
|
85
|
+
private _debug;
|
|
86
|
+
private _helloCount;
|
|
73
87
|
/**
|
|
74
88
|
* @param role 角色,省略时按 window.worklink.plugin 是否存在自动探测
|
|
75
89
|
* @param options 超时配置
|
|
76
90
|
* @throws 依赖未就绪时抛出(window.worklink;监听后端可稍后出现,不算构造失败)
|
|
77
91
|
*/
|
|
78
92
|
constructor(role?: BridgeRole, options?: BridgeOptions);
|
|
93
|
+
/** debug 日志(options.debug 开启时打印,前缀带角色便于双端对照) */
|
|
94
|
+
private _log;
|
|
79
95
|
/** 校验依赖是否就绪,缺失抛出明确异常 */
|
|
80
96
|
private _checkDeps;
|
|
81
97
|
/** 绑定消息监听:优先 waltz;无 waltz 时定义/包装 window.handleMessageFromNative */
|
|
@@ -85,13 +101,21 @@ export default class LightAppBridge {
|
|
|
85
101
|
/** 处理一条归一化后的消息 */
|
|
86
102
|
private _onMessage;
|
|
87
103
|
/**
|
|
88
|
-
*
|
|
104
|
+
* 建立连接(握手)。构造时已自动调用,通常无需手动调。
|
|
105
|
+
* - 已连接 / 握手进行中:幂等,返回同一个 Promise
|
|
106
|
+
* - 上次握手失败:重新发起(内部自动重置状态,无需重建实例——
|
|
107
|
+
* 典型场景:插件先启动、轻应用窗口尚未打开导致超时,对端就绪后再次 connect 即可)
|
|
108
|
+
* - 实例已销毁:reject
|
|
109
|
+
* 行为:
|
|
89
110
|
* - 插件:发起握手(解析目标 id → 发 hello → 每秒重试直到收到 ack 或超时)
|
|
90
|
-
* - 轻应用:被动等待 hello
|
|
91
|
-
* 多次调用幂等,返回同一个连接 Promise。
|
|
111
|
+
* - 轻应用:被动等待 hello(持续监听,不超时)
|
|
92
112
|
* @returns 对端 webContentsId
|
|
93
113
|
*/
|
|
94
114
|
connect(): Promise<number | null>;
|
|
115
|
+
/** 重置连接状态(用于首次握手或失败后重连) */
|
|
116
|
+
private _resetConnectState;
|
|
117
|
+
/** 连接失败:标记失败并 reject(再次 connect 可重试) */
|
|
118
|
+
private _failConnect;
|
|
95
119
|
/** 发送 hello(携带自身 webContentsId) */
|
|
96
120
|
private _sendHello;
|
|
97
121
|
/** 收到 hello(轻应用侧):记录对端、回 ack、完成握手 */
|
|
@@ -132,7 +156,7 @@ export default class LightAppBridge {
|
|
|
132
156
|
* @returns 调用以取消监听
|
|
133
157
|
*/
|
|
134
158
|
onMessage(handler: MessageHandler): () => void;
|
|
135
|
-
/**
|
|
159
|
+
/** 销毁实例:解绑消息监听、清空待处理请求、停止握手重试。销毁后实例不可再用 */
|
|
136
160
|
destroy(): void;
|
|
137
161
|
}
|
|
138
162
|
/**
|
package/dist/lightAppBridge.js
CHANGED
|
@@ -26,7 +26,21 @@ const PROTOCOL_VERSION = 1; // 协议版本号
|
|
|
26
26
|
const DEFAULT_TIMEOUT = 3000; // send 默认超时(ms)
|
|
27
27
|
const DEFAULT_HANDSHAKE_TIMEOUT = 30000; // 握手超时(ms)
|
|
28
28
|
const HELLO_RETRY_INTERVAL = 1000; // 插件 hello 重试间隔(ms)
|
|
29
|
+
const DEBUG_PAYLOAD_LIMIT = 500; // debug 日志 payload 截断长度
|
|
29
30
|
const genId = () => 'r_' + Date.now().toString(36) + '_' + Math.random().toString(36).slice(2, 7);
|
|
31
|
+
/** debug 日志用:安全序列化 payload,超长截断 */
|
|
32
|
+
function debugPayload(data) {
|
|
33
|
+
let s;
|
|
34
|
+
try {
|
|
35
|
+
s = typeof data === 'string' ? data : JSON.stringify(data);
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
s = String(data);
|
|
39
|
+
}
|
|
40
|
+
if (s === undefined)
|
|
41
|
+
s = 'undefined';
|
|
42
|
+
return s.length > DEBUG_PAYLOAD_LIMIT ? s.slice(0, DEBUG_PAYLOAD_LIMIT) + `…(截断,共${s.length}字符)` : s;
|
|
43
|
+
}
|
|
30
44
|
/** 判断是否为本 SDK 的消息(按 __sdk 标识过滤) */
|
|
31
45
|
const isBridgeMsg = (msg) => !!(msg && typeof msg === 'object' && msg.__sdk === SDK_ID);
|
|
32
46
|
/** 创建一个可外部 resolve 的 Promise */
|
|
@@ -163,6 +177,9 @@ export default class LightAppBridge {
|
|
|
163
177
|
this._started = false;
|
|
164
178
|
this._unlisten = null;
|
|
165
179
|
this._listenerReady = null;
|
|
180
|
+
this._connectFailed = false;
|
|
181
|
+
this._destroyed = false;
|
|
182
|
+
this._helloCount = 0;
|
|
166
183
|
let r = role === 'plugin' || role === 'lightapp' ? role : 'lightapp';
|
|
167
184
|
if (role !== 'plugin' && role !== 'lightapp') {
|
|
168
185
|
const wl = window.worklink;
|
|
@@ -171,6 +188,11 @@ export default class LightAppBridge {
|
|
|
171
188
|
this.role = r;
|
|
172
189
|
this.timeout = options.timeout != null ? options.timeout : DEFAULT_TIMEOUT;
|
|
173
190
|
this.handshakeTimeout = options.handshakeTimeout != null ? options.handshakeTimeout : DEFAULT_HANDSHAKE_TIMEOUT;
|
|
191
|
+
this._debug = !!options.debug;
|
|
192
|
+
this._log('构造: role=' + r + ', timeout=' + this.timeout +
|
|
193
|
+
', handshakeTimeout=' + this.handshakeTimeout +
|
|
194
|
+
', 监听后端=' + (hasWaltz() ? 'waltz' : 'handleMessageFromNative') +
|
|
195
|
+
', 自身id=' + this.getId());
|
|
174
196
|
// 连接 deferred:构造时即建立,保证轻应用收到 hello 也能 resolve(无需显式 connect)
|
|
175
197
|
this._connectDeferred = deferred();
|
|
176
198
|
this._connectPromise = this._connectDeferred.promise.then((peerId) => {
|
|
@@ -181,6 +203,12 @@ export default class LightAppBridge {
|
|
|
181
203
|
this._startListener(); // 绑定消息监听(waltz 或定义 handleMessageFromNative)
|
|
182
204
|
this.connect(); // 构造即自动发起握手(内部会等监听就绪)
|
|
183
205
|
}
|
|
206
|
+
/** debug 日志(options.debug 开启时打印,前缀带角色便于双端对照) */
|
|
207
|
+
_log(...args) {
|
|
208
|
+
if (!this._debug)
|
|
209
|
+
return;
|
|
210
|
+
console.log(`[LightAppBridge:${this.role}]`, ...args);
|
|
211
|
+
}
|
|
184
212
|
/** 校验依赖是否就绪,缺失抛出明确异常 */
|
|
185
213
|
_checkDeps() {
|
|
186
214
|
const w = window;
|
|
@@ -204,7 +232,7 @@ export default class LightAppBridge {
|
|
|
204
232
|
})
|
|
205
233
|
.catch((e) => {
|
|
206
234
|
// 理论上不会发生(无 waltz 时必走定义路径),保险起见让连接失败并给出原因
|
|
207
|
-
this.
|
|
235
|
+
this._failConnect(new Error('LightAppBridge 监听后端绑定失败 (' +
|
|
208
236
|
(e && e.message ? e.message : String(e)) + ')'));
|
|
209
237
|
});
|
|
210
238
|
}
|
|
@@ -216,8 +244,12 @@ export default class LightAppBridge {
|
|
|
216
244
|
_onMessage(msg) {
|
|
217
245
|
const envelope = msg.envelope;
|
|
218
246
|
const fromId = msg.fromWebContentsId;
|
|
219
|
-
if (!isBridgeMsg(envelope))
|
|
247
|
+
if (!isBridgeMsg(envelope)) {
|
|
248
|
+
this._log('recv← 忽略非本SDK消息: from=' + fromId);
|
|
220
249
|
return;
|
|
250
|
+
}
|
|
251
|
+
this._log('recv← type=' + envelope.type + ' id=' + envelope.id +
|
|
252
|
+
' from=' + fromId + ' data=' + debugPayload(envelope.data));
|
|
221
253
|
switch (envelope.type) {
|
|
222
254
|
case 'hello':
|
|
223
255
|
this._onHello(fromId);
|
|
@@ -236,16 +268,27 @@ export default class LightAppBridge {
|
|
|
236
268
|
}
|
|
237
269
|
// —— 连接 / 握手 —— //
|
|
238
270
|
/**
|
|
239
|
-
*
|
|
271
|
+
* 建立连接(握手)。构造时已自动调用,通常无需手动调。
|
|
272
|
+
* - 已连接 / 握手进行中:幂等,返回同一个 Promise
|
|
273
|
+
* - 上次握手失败:重新发起(内部自动重置状态,无需重建实例——
|
|
274
|
+
* 典型场景:插件先启动、轻应用窗口尚未打开导致超时,对端就绪后再次 connect 即可)
|
|
275
|
+
* - 实例已销毁:reject
|
|
276
|
+
* 行为:
|
|
240
277
|
* - 插件:发起握手(解析目标 id → 发 hello → 每秒重试直到收到 ack 或超时)
|
|
241
|
-
* - 轻应用:被动等待 hello
|
|
242
|
-
* 多次调用幂等,返回同一个连接 Promise。
|
|
278
|
+
* - 轻应用:被动等待 hello(持续监听,不超时)
|
|
243
279
|
* @returns 对端 webContentsId
|
|
244
280
|
*/
|
|
245
281
|
connect() {
|
|
246
282
|
var _a;
|
|
247
|
-
if (this.
|
|
283
|
+
if (this._destroyed) {
|
|
284
|
+
return Promise.reject(new Error('实例已销毁,请重建实例'));
|
|
285
|
+
}
|
|
286
|
+
if (this._connected)
|
|
248
287
|
return this._connectPromise;
|
|
288
|
+
if (this._connectStarted && !this._connectFailed)
|
|
289
|
+
return this._connectPromise;
|
|
290
|
+
// 首次调用,或上次握手失败:重置连接状态重新发起
|
|
291
|
+
this._resetConnectState();
|
|
249
292
|
this._connectStarted = true;
|
|
250
293
|
// 等监听后端绑定完成后再握手,避免对端的 ack/hello 在监听绑定前到达而丢失
|
|
251
294
|
const listenerReady = (_a = this._listenerReady) !== null && _a !== void 0 ? _a : Promise.resolve();
|
|
@@ -254,7 +297,7 @@ export default class LightAppBridge {
|
|
|
254
297
|
if (this.role === 'plugin') {
|
|
255
298
|
this._handshakeTimer = setTimeout(() => {
|
|
256
299
|
if (!this._connected) {
|
|
257
|
-
this.
|
|
300
|
+
this._failConnect(new Error(`握手超时 (${this.handshakeTimeout}ms),对端未响应`));
|
|
258
301
|
this._clearHelloTimer();
|
|
259
302
|
}
|
|
260
303
|
}, this.handshakeTimeout);
|
|
@@ -280,27 +323,54 @@ export default class LightAppBridge {
|
|
|
280
323
|
}
|
|
281
324
|
// lightapp 被动等待 hello(listener 已绑定),收到后在 _onHello 中回 ack 并 resolve
|
|
282
325
|
})
|
|
283
|
-
.catch((e) => this.
|
|
326
|
+
.catch((e) => this._failConnect(e));
|
|
284
327
|
return this._connectPromise;
|
|
285
328
|
}
|
|
329
|
+
/** 重置连接状态(用于首次握手或失败后重连) */
|
|
330
|
+
_resetConnectState() {
|
|
331
|
+
this._connectDeferred = deferred();
|
|
332
|
+
this._connectPromise = this._connectDeferred.promise.then((peerId) => {
|
|
333
|
+
this._onConnected(peerId);
|
|
334
|
+
return peerId;
|
|
335
|
+
});
|
|
336
|
+
this._connectFailed = false;
|
|
337
|
+
this._connectStarted = false;
|
|
338
|
+
this._clearHelloTimer();
|
|
339
|
+
if (this._handshakeTimer) {
|
|
340
|
+
clearTimeout(this._handshakeTimer);
|
|
341
|
+
this._handshakeTimer = null;
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
/** 连接失败:标记失败并 reject(再次 connect 可重试) */
|
|
345
|
+
_failConnect(e) {
|
|
346
|
+
if (this._destroyed)
|
|
347
|
+
return;
|
|
348
|
+
this._connectFailed = true;
|
|
349
|
+
this._log('✗ 握手失败: ' + (e && e.message ? e.message : String(e)));
|
|
350
|
+
this._connectDeferred.reject(e instanceof Error ? e : new Error(String(e)));
|
|
351
|
+
}
|
|
286
352
|
/** 发送 hello(携带自身 webContentsId) */
|
|
287
353
|
_sendHello() {
|
|
288
354
|
if (this._target == null)
|
|
289
355
|
return;
|
|
356
|
+
this._helloCount++;
|
|
357
|
+
this._log('hello→ 目标=' + this._target + (this._helloCount > 1 ? ' (重试#' + this._helloCount + ')' : ''));
|
|
290
358
|
this._send(this._target, this._envelope('hello', { from: this.getId() }));
|
|
291
359
|
}
|
|
292
360
|
/** 收到 hello(轻应用侧):记录对端、回 ack、完成握手 */
|
|
293
361
|
_onHello(fromId) {
|
|
294
|
-
if (fromId
|
|
295
|
-
|
|
362
|
+
if (fromId == null)
|
|
363
|
+
return; // 无法定位对端则忽略(真实环境该字段恒有值),握手不完成
|
|
364
|
+
this._recordPeer(fromId);
|
|
296
365
|
// 回 ack,携带自身 webContentsId
|
|
297
|
-
|
|
298
|
-
this._send(fromId, this._envelope('ack', { from: this.getId() }));
|
|
366
|
+
this._send(fromId, this._envelope('ack', { from: this.getId() }));
|
|
299
367
|
// 握手完成(resolve 幂等,重复 hello 只回 ack)
|
|
300
368
|
this._connectDeferred.resolve(fromId);
|
|
301
369
|
}
|
|
302
370
|
/** 收到 ack(插件侧):确认连接 */
|
|
303
371
|
_onAck(fromId) {
|
|
372
|
+
if (fromId == null)
|
|
373
|
+
return; // 无法定位对端则忽略
|
|
304
374
|
this._recordPeer(fromId);
|
|
305
375
|
this._connectDeferred.resolve(fromId);
|
|
306
376
|
}
|
|
@@ -310,6 +380,7 @@ export default class LightAppBridge {
|
|
|
310
380
|
}
|
|
311
381
|
_onConnected(peerId) {
|
|
312
382
|
this._connected = true;
|
|
383
|
+
this._log('✓ 连接建立: 对端=' + peerId + (this._helloCount > 1 ? ' (hello共' + this._helloCount + '次)' : ''));
|
|
313
384
|
this._clearHelloTimer();
|
|
314
385
|
if (this._handshakeTimer) {
|
|
315
386
|
clearTimeout(this._handshakeTimer);
|
|
@@ -362,19 +433,24 @@ export default class LightAppBridge {
|
|
|
362
433
|
Promise.allSettled(results).then((settled) => {
|
|
363
434
|
for (const s of settled) {
|
|
364
435
|
if (s.status === 'fulfilled' && s.value !== undefined) {
|
|
436
|
+
this._log('res→ id=' + id + ' data=' + debugPayload(s.value));
|
|
365
437
|
this._send(this._peer, this._envelope('res', s.value, id));
|
|
366
438
|
return;
|
|
367
439
|
}
|
|
368
440
|
}
|
|
441
|
+
this._log('✗ req 无可回复值(回调全空/异常): id=' + id);
|
|
369
442
|
});
|
|
370
443
|
}
|
|
371
444
|
/** 收到 res:按 id 唤醒等待中的 send */
|
|
372
445
|
_serveRes(envelope) {
|
|
373
446
|
const p = this._pending.get(envelope.id);
|
|
374
|
-
if (!p)
|
|
447
|
+
if (!p) {
|
|
448
|
+
this._log('recv← res 无等待者(可能已超时): id=' + envelope.id);
|
|
375
449
|
return;
|
|
450
|
+
}
|
|
376
451
|
clearTimeout(p.timer);
|
|
377
452
|
this._pending.delete(envelope.id);
|
|
453
|
+
this._log('✓ 收到响应 id=' + envelope.id + ' data=' + debugPayload(envelope.data));
|
|
378
454
|
p.resolve(envelope.data);
|
|
379
455
|
}
|
|
380
456
|
/** 底层发送:把信封投递到指定 webContentsId */
|
|
@@ -402,14 +478,18 @@ export default class LightAppBridge {
|
|
|
402
478
|
* @returns 对端回调返回的数据
|
|
403
479
|
*/
|
|
404
480
|
send(data, options = {}) {
|
|
481
|
+
if (this._destroyed)
|
|
482
|
+
return Promise.reject(new Error('实例已销毁'));
|
|
405
483
|
const timeout = options.timeout != null ? options.timeout : this.timeout;
|
|
406
484
|
return this.ready().then((targetId) => {
|
|
407
485
|
const id = genId();
|
|
408
486
|
const envelope = this._envelope('req', data, id);
|
|
487
|
+
this._log('send→ id=' + id + ' 目标=' + targetId + ' data=' + debugPayload(data));
|
|
409
488
|
return new Promise((resolve, reject) => {
|
|
410
489
|
const timer = setTimeout(() => {
|
|
411
490
|
if (this._pending.has(id)) {
|
|
412
491
|
this._pending.delete(id);
|
|
492
|
+
this._log('✗ 超时 id=' + id + ' (' + timeout + 'ms 无响应)');
|
|
413
493
|
reject(new Error(`请求超时 (${timeout}ms)`));
|
|
414
494
|
}
|
|
415
495
|
}, timeout);
|
|
@@ -437,8 +517,12 @@ export default class LightAppBridge {
|
|
|
437
517
|
this._messageHandlers.splice(i, 1);
|
|
438
518
|
};
|
|
439
519
|
}
|
|
440
|
-
/**
|
|
520
|
+
/** 销毁实例:解绑消息监听、清空待处理请求、停止握手重试。销毁后实例不可再用 */
|
|
441
521
|
destroy() {
|
|
522
|
+
if (this._destroyed)
|
|
523
|
+
return;
|
|
524
|
+
this._destroyed = true;
|
|
525
|
+
this._log('销毁实例: 未完成请求=' + this._pending.size);
|
|
442
526
|
if (this._unlisten) {
|
|
443
527
|
try {
|
|
444
528
|
this._unlisten();
|
|
@@ -451,6 +535,8 @@ export default class LightAppBridge {
|
|
|
451
535
|
clearTimeout(this._handshakeTimer);
|
|
452
536
|
this._handshakeTimer = null;
|
|
453
537
|
}
|
|
538
|
+
// 进行中的握手直接失败(已 resolve 的话 reject 是 no-op)
|
|
539
|
+
this._connectDeferred.reject(new Error('实例已销毁'));
|
|
454
540
|
// 拒绝所有未完成的请求
|
|
455
541
|
this._pending.forEach((p) => {
|
|
456
542
|
clearTimeout(p.timer);
|