我有这样的设置:我正在尝试使用自定义事件处理程序来处理.data
哈希并在处理程序运行后“垃圾收集”它的项目,以避免将它们不必要地保留在内存中,等等.defer()
函数模拟我得到的函数,它根据提供的异步运行函数生成函数,尝试模仿本机事件处理方式......
令我困惑的是,在调用延迟函数之后,通过分配... = null;
删除数据项似乎在函数执行之前运行,基本上反转执行顺序(?!),留下一个没有数据可用的函数。 ..
这是我的脚本:
//
//
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
答案 0 :(得分:1)
因此,正如Bergi所说,你观察到的行为是预期的。在任何异步调用开始之前,主调用堆栈总是完成。如果您对defer
的呼叫超过1次,您甚至不知道哪一个会先执行。
为什么不在action
函数调用中清理数组?我知道它可能打破了实施的逻辑,并不总是可行的。如果是这样,您可能希望使用本机事件。例如,在这种情况下使用MutationObserver可能是一个有趣的想法。
DOMElement
mutations.forEach(function(mutation)
抓取变异并使阵列无效。但无论如何,我认为你不应该试图“猜测”什么时候取消指针。根据定义,调用异步函数意味着您不知道何时完成。
希望有所帮助