1

我有一个 Dart js-interop 回调,它反过来将一个 javascript 回调作为参数。dart 回调实现如下所示:

void callBackToDartCode(String query, js.FunctionProxy completionCallback) {
  js.context.completionCallback = completionCallback;
  doSomethingAscyn(query).then(
    (result) {
       // hand the query result back to the javascript code
       js.context.completionCallback(js.map(result));
  });

这行得通。完成这项工作的关键是将 FunctionProxy 保存在 js.context 中,以便在异步“then”方法中执行它时可用。这行代码很重要:

js.context.completionCallback = completionCallback;

如果未完成,则不会保留 completeCallback,因此在异步操作完成时无法调用。

我没有见过这样的例子,我不确定我是否真的正确地做到了这一点。

它提出了以下问题:

  1. 调用完“completeCallback”与 js.context 后如何解除关联?它是否永远与 js.context 保持关联?
  2. 如果同时进行多个异步操作,则在 js.context 中使用名称“completionCallback”似乎会发生冲突。这让我觉得这是一个普遍的问题。js-interop 有办法解决这个问题,还是我的工作是管理它?
4

1 回答 1

1

使用js-interop,所有代理的范围都可以防止内存泄漏。这意味着Proxy它将在其关联范围的末尾丢失其 JS 对象引用。如果scoped((){})函数未明确使用,则在第一次完成互操作操作时初始化惰性作用域,并在当前事件循环结束时自动关闭作用域。如果你想让 aProxy比它的关联范围更长寿,你必须保留它。这可以通过js.retain(proxy). 一旦不再需要您的代理,您可以使用js.release(proxy).

因此你的代码应该是:

void callBackToDartCode(String query, js.FunctionProxy completionCallback) {
  js.retain(completionCallback);
  doSomethingAscyn(query).then(
    (result) {
       // hand the query result back to the javascript code
       completionCallback(js.map(result));
       // completionCallback is no longer used
       js.release(completionCallback);
  });
}

关于您关于从 js.context 取消关联“completeCallback”的问题,您可以使用js.deleteProperty(js.context, "completeCallback")

于 2013-06-01T19:49:21.400 回答