2014-06-07 82 views
1

我有这种设置:我试图使用自定义事件处理程序处理.data哈希和“垃圾收集”这是处理程序已经运行项目后,避免让他们不必要在内存中等.defer()功能模拟我得到的,它生成的功能基于提供的异步运行,试图模仿本地事件处理的方式...

让我困惑的是,删除数据项分配... = null;,要求延期功能之后,似乎之前的功能得到执行,基本上颠倒执行顺序(?!)运行,留下一个函数没有数据与...
工作3210 这里的脚本我有:异步功能“后清理”

// 
    // 
    var defer = function(func) { 

    // get asynchronoused `.func()` version 
    return function() { 

     // cache inputs for use by defered function 
     var args = arguments; 
     var node = this; 

     return setTimeout(
     function() { 
      func.apply(node, args); 
     } 
    ), node; 

    }; 
    }; 


    var action = function(node) { 
    // process a node 
    console.log(node['@foo']['txt']); 
    }; 


    var data = { 

    '@foo': { 
     'id' : '#foo', 
     'tag' : 'h2', 
     'txt' : 'stuff', 
    }, 

    '@spam': { 
     'id' : '#spam', 
     'tag' : 'h1', 
     'txt' : 'and shit', 
    }, 
    }; 

    // run `.action()` asynchronously 
    defer(action)(data); 

    // garbage collect after 
    data['@foo'] = null; 
    // this part seems to run before function call 
    // cleaning the data before `defer(action)(data);` gets it's time 
    // it throws error here because `null` gc-ed it right away (or something) 
    // TypeError: node['@foo'] is null 
    // 


我目前正在围绕这一问题的工作由该会运行清理回调数据得到处理之后,这似乎很别扭提供额外的功能( _finaly())和不自然到简单的事情..问题是为什么片段代码似乎运行不顺利,并且 这里究竟发生了什么或者是否有更简洁的方法来解决问题

这里的解决方案到目前为止我有:

var action = function(node, _finaly) { 
    // provide `._finaly()` callback 
    // that will run after processing gets done 
    ///// 

    console.log(node['@foo']['txt']); 

    // .. and run the cleanup code 
    _finaly && _finaly(node, 'txt'); 

    }; 

    defer(action)(data, function (node, item) { 
    // do the house-keep in a callback here 
    // rather than directly after execution 
    node.hasOwnProperty(item) && (node[item] = null); 
    }); 
    // 
    // eof 
+1

由于它是*异步*! – Bergi

+1

是的,你的解决方案与其他回调基本上是一条路。你甚至可能甚至不修改'action',而只是简单地包装它(因为它本身是同步的),并且可能使用其他一些更高级的函数来获得更好看的代码。 – Bergi

回答

1

所以,BERGI说,你观察到的行为是可以预期的。主调用堆栈总是在任何异步调用开始之前完成。如果你有一个以上的电话给defer,你甚至不知道哪一个会先执行。

你为什么不只是清理你的action函数调用数组?我知道这可能会破坏执行的逻辑,并不总是可行的。如果是这样,您可能希望使用本地事件。例如,在这种情况下使用MutationObserver可能是一个有趣的想法。

  1. 观察你的选择
  2. 的隐藏DOMElement当你做,你要废了指针,改变元素的属性
  3. 赶上突变与mutations.forEach(function(mutation)并注销您的阵列。

但无论如何,我不认为你应该尝试“猜测”何时取消指针。根据定义,调用异步函数意味着您不知道何时完成。

希望它有帮助

+1

如果您可以在异步代码中注入“隐藏DOM元素中的属性更改”,那么还可以注入回调调用。更简单和跨浏览器安全。 – Bergi

+0

是的,你是对的,还有其他的方式,当然更清洁(但正如我所说,这个想法很有趣)。但是使用回调调用不会使用常规事件堆栈。 MutationObserver的确。 – Sebas

+0

啊,我明白你在做什么,尽管我不确定什么是单独的堆栈框架。除了乐趣。 – Bergi