添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
相关文章推荐
爱运动的手电筒  ·  Spring boot + Spring ...·  4 月前    · 
聪明伶俐的刺猬  ·  Monitoring NVIDIA GPU ...·  10 月前    · 
热心的罐头  ·  curl_easy_escape ...·  1 年前    · 
没读研的毛衣  ·  jquery选择器 之 ...·  1 年前    · 

[sc name="zhuanzai" author="Barranca" link=" https://www.davidebarranca.com/2014/12/html-panels-tips-15-asynchronous-vs-synchronous-evalscript/ " ][/sc]

引用 StackOverflow

当您同步执行某事时,您会等待它完成,然后再继续执行另一个任务。当您异步执行某件事时,您可以在它完成之前继续执行另一个任务。

或者视觉上:

早期 evalScript 是同步的,现在则是异步的:

CSXSInterface.instance.evalScript('jsxFunction'); // Sync 同步
csInterface().evalScript('jsxFunction'); // Async 异步

evalScript 函数需要两个参数:

  • 要运行的 ExtendScript 代码。
  • 一个回调函数,它反过来将来自 ExtendScript 调用的返回值作为参数。
  • 默认行为如下:

    var csInterface = new CSInterface();
    var username = undefined;
    // AE 脚本中 获取当前系统用户名
    csInterface.evalScript('system.userName', function(result) {
      username = result;
    alert(username); // undefined
    

    在上面的例子中,system.userName执行后会直接返回——当前在 AE中的数据被传递给回调,回调将其分配给变量username。由于evalScript的异步性质,最后一句显示“未定义” :第 6 行还未执行完毕,解释器就会继续执行到第 9 行而不等待 ExtendScript 返回(4~7行),因此username 仍然是undefined

    就如同:你让你老婆出去买东西,然后她前脚刚出门,你就打开冰箱说“老婆!你买的东西呢!”

    同步解决方法

    有几种不同的方法可以模拟同步行为

    1.设置超时

    最简单的方法:等你老婆从商店回来:

    var csInterface = new CSInterface();
    var username = undefined;
    csInterface.evalScript('system.userName', function (result) {
      username = result;
    setTimeout(alert(username), 500);  // 延迟500ms再弹窗
    

    这并不理想。因为不知道要等待多长时间  –  这取决于要执行的 ExtendScript 代码。

    2. 在回调中嵌套代码

    如果alert在回调中使用,则它可以正常工作:

    var csInterface = new CSInterface();
    var username = undefined;
    csInterface.evalScript('system.userName', function (result) {
      username = result;
      alert(username);
    

    当然,这会导致所谓的回调地狱 ——将 evalScript 调用嵌套在另一个调用中,例如:

    csInterface.evalScript('/* 你的代码1 */', function(result) {
      csInterface.evalScript('/* 你的代码2 */', function (result) {
        // 等等
    

    如果你没有特别的需求,它也能凑合用。

    3. 事件驱动回调

    从 CEP 5.2 开始支持此方法。可以通过PlugPlugExternalObject实现自定义事件,这些事件由 ExtendScript 调度并从 JS 侦听。

    先把 ExtendScript 代码放在 JSX 文件中:

    // in jsx file
    function get_username() {
        // 调用lib
        try {
            var xLib = new ExternalObject("lib:PlugPlugExternalObject");  // 老版本用lib://  ?待验证
        } catch (e) {
            return false;
        var eventObj = new CSXSEvent(); // 创建事件对象
        eventObj.type = "my_event";     // 创建事件类型,用于外部验证
        eventObj.data = system.userName;// 输入事件数据
        eventObj.dispatch();            // 发送事件
        xLib.unload();                  // 注销lib?
        return true;
    

    然后在 JS 中设置监听器,用于监听数据的接受;

    var csInterface = new CSInterface();
    // 监听
    csInterface.addEventListener("my_event", function (event) {
        alert(event.data);  // 返回接受的数据
    // 判断是否正常执行lib
    csInterface.evalScript("get_username()", function (result) {
        if (result == false) {
            alert("There's been a problem.");
    

    请注意,正如Kris Coppieters等其他开发人员所假设的那样,“即使您设法从 JS 的不同部分进行多个 JSX 调用,也可能无法同时运行多个 ExtendScript ”。

    (1)如果3的事件是绑定在单击事件上的,你需要先侦听获取事件,再处理完事件后,注销。否则每次单击都会只addListen,多次执行

    function test() {
        var csInterface = new CSInterface();
        function get_data(event) {
            alert(event.data);
            csInterface.removeEventListener("my_event", get_data);
        csInterface.addEventListener("my_event", get_data);
        csInterface.evalScript("get_username()", function (result) {
            if (result == false) {
                alert("未成功加载lib");
    

    (2)JSX传回js的类型为字符串,所以想传对象回来,需要先在JSX里return JSON.stringify(你的对象),然后在js里 JSON.parse(返回值)