# aardio 范例: web.view 回调 JS 函数对象



```aardio
import win.ui;
/*DSG{{*/
var winform = win.form(text="web.view 回调 JS 函数对象";right=757;bottom=467)
winform.add()
/*}}*/

import web.view;
var wb = web.view(winform);

/*
第一原则：在 JS 与 aardio 代码交互时应避免同步发起反向调用。
违反此原则可能导致 WebView2 调用异常、卡顿等问题。

- 在 aardio 中调用 JS 总是异步发起调用，
但 调用 wb.eval, wb.xcall 时默认会阻塞等待 JS 返回值，
除非在指定了接收 JS 返回值的回调函数（异步调用，不会阻塞调用代码）。

在被网页回调的 aardio 函数内部应避免阻塞调用导致阻塞后续调用。
如果不需要返回值，改用 wb.invoke, wb.doScript 更轻量且不需要处理返回值与回调。
或者通过 winform.setTimeout, thread.invoke 也可以异步执行代码。

- 在 JS 中虽然 aardio 函数的返回值是异步对象，但这不等于发起调用的过程是异步的。
一个正被 aardio 回调的 JS 函数内如果要反向回调 aardio，则应通过 setTimeout 异步发起调用。
*/
	
wb.external = {
	test = function(jsCallback){ 
		/*
		使用 wb.external 与 JavaScript 交互则是基于 COM 接口。
		除了字符串、数值、布尔值、时间值、buffer 这些基于传值的类型可以兼容以外，
		其他需要传址的 JS 对象（例如 JS 函数）在 aardio 中则是 COM 对象。
		COM 对象可以保持对原 JS 对象的引用，作为参数传回 JS 仍然会是原来的 JS 对象。
		
		jsCallback 参数是一个 JS 函数对象，在 aardio 中可以直接使用。
		但 aardio 中的 JS 函数对象基于 COM 接口，并且只能是异步非阻塞调用（不会等待返回值）。
		*/
		jsCallback("回调 JavaScript 函数的参数",jsCallback);//正确用法！非阻塞，异步发起调用
		
		/*
		要避免在 JS 回调本地函数时再去阻塞调用 JS，就好比自己不能把自己抬起来。
		这可能导致 WebView2 异常（例如死锁没反应，甚至退出进程重新运行也会异常）
		
		调用 wb.eval, wb.xcall 时默认会阻塞等待 JS 返回值，
		除非在指定了接收 JS 返回值的回调函数（异步调用，不会阻塞调用代码）。
		在被网页回调的 aardio 函数内部应避免阻塞调用导致阻塞后续调用。
		如果不需要返回值，改用 wb.invoke, wb.doScript 更轻量且不需要处理返回值与回调
		
		调用 JS 函数: https://www.aardio.com/zh-cn/docs/examples/WebUI/web.view/xcall.html
		*/
		//wb.xcall("jsFunc","arg1"); //错误用法！
		
		// wb.invoke, wb.doScript 都是非阻塞异步调用，不等待也不会获取返回值
		wb.invoke("jsFunc","invoke"); //正确用法，使用 WebView2 异步调用优于同步阻塞调用
		wb.doScript("jsFunc('doScript')"); //正确用法，使用 WebView2 异步调用优于同步阻塞调用
		winform.setTimeout( function(){ 
			//可能阻塞的代码放在这里
			//var ret = wb.invoke("jsFunc","invoke"); 
		});
		
		thread.invoke( 
			function(wb){
				//aardio 中优先使用异步调用 JS 的方式
				//wb.invoke("jsFunc","invoke"); 
			},wb
		)	
	};
}

 
wb.html = /********
<!doctype html>
<html><head>
	<meta charset="utf-8">
	<style type="text/css">html,body{ height:100%; margin:0; } </style>
	<script> 
	(async()=>{
		jsFunc = function(arg1){
			document.write(arg1," ");
		}
		
		await aardio.test(
			function(str){
				alert(str);
			} 
		); 	
	})()
	</script>
</head>
<body></body></html>
********/

winform.show();
win.loopMessage();

```

