2013-06-01 54 views
1

我有一個Dart js-interop回調,它將JavaScript回調作爲參數。飛鏢回調實現如下所示:dart js-interop FunctionProxy回調關係到js.context

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中,以便在需要在async「then」方法中執行它時可用。這行代碼是很重要的:

js.context.completionCallback = completionCallback; 

如果沒有這樣做,則completeCallback不會保留,因此異步操作完成時,無法調用。

我還沒有見過這樣的例子,我不確定我是否真的做到了這一點。

它提出的問題:

  1. 如何撇清 「completeCallback」 從js.context我打過電話後呢?它是否永遠與js.context保持關聯?
  2. 如果多個異步操作正在同時進行,js.context中會出現名稱爲「completionCallback」的衝突使用。這使我感到常見問題。 js-interop是否有辦法處理這個問題,還是我的工作來管理它?

回答

1

With js-interop所有代理的作用域都是爲了防止內存泄漏。這意味着Proxy將在其關聯範圍的末尾丟失其JS對象引用。如果scoped((){})函數沒有明確使用,則在第一次完成互操作操作時會初始化惰性範圍,並且範圍在當前事件循環結束時自動關閉。如果您想使Proxy的壽命長於其關聯的範圍,則必須保留它。這可以通過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); 
    }); 
} 

關於你的問題有關解除關聯「completeCallback」從js.context你可以有js.deleteProperty(js.context, "completeCallback")

+0

我實際使用js.retain(開始時做了completionCallback),但該調用會生成「Illegal type:funcref」異常。這就是那讓我嘗試了我發佈的代碼。 (我錯過了文檔中的deleteProperty - 很明顯,謝謝) – jptknta

+0

看來現在還不支持FunctionProxy。請[提交問題](https://github.com/dart-lang/js-interop/issues/new)。 –

+1

[issue filed](http://github.com/dart-lang/js-interop/issues/83) – jptknta