2014-06-07 3 views
1

나는 이런 종류의 설정을 가지고있다. 사용자 정의 이벤트 처리기를 사용하여 .data 해시를 처리하고 처리기를 실행 한 후 가비지 수집하여 불필요하게 보관하지 못하게하려고한다. 메모리 등등 .defer() 함수는 내가 얻은 것을 시뮬레이션하고, 비동기 적으로 실행되는 제공되는 함수를 기반으로 함수를 생성하여 원시 이벤트 처리를 모방하려고합니다 ...

저를 혼란시키는 것은 데이터 항목을 삭제하는 것입니다. ... = null;을 할당 한 후 deferred 함수를 호출 한 후 함수가 실행되기 전에 실행되는 것처럼 보이며 기본적으로 실행 순서 (?!)를 반전하여 작업 할 데이터가없는 함수가 남습니다.

여기 내가 가지고있는 스크립트입니다 :비동기 함수 'post-cleanup'

// 
    // 
    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에 1 번 이상 전화를했다면 어느 것이 먼저 실행되는지 알지 못할 것입니다.

action 함수 호출에서 배열을 정리하지 않는 이유는 무엇입니까? 나는 그것이 실행의 논리를 깨뜨릴 수도 있고 항상 실현 가능한 것은 아니라는 점을 이해합니다. 그렇다면 기본 이벤트를 대신 사용할 수 있습니다. 예를 들어, MutationObserver을 사용하면이 경우 재미있는 아이디어가 될 수 있습니다.

  1. 당신은 당신의 선택
  2. 의 숨겨진 DOMElement을 완료 관찰하십시오 때, 당신은, 포인터를 무효화 mutations.forEach(function(mutation)로 요소의 속성
  3. 캐치 돌연변이를 변경하고 배열을 무효화하고 싶다.

그러나 어쨌든 포인터를 무효화 할 때 "추측"하려고하지 않아도됩니다. 비동기 함수를 호출하면 정의에 따라 완료 시점을 알 수 없습니다.

희망 하시겠습니까?

+1

숨겨진 DOM 요소의 속성 변경을 비동기 코드에 삽입 할 수 있다면 콜백 호출을 삽입 할 수 있습니다. 훨씬 간단하고 브라우저 간 안전. – Bergi

+0

예, 맞습니다. 다른 방법이 있습니다. 분명히 훨씬 더 깨끗합니다. (하지만 제가 말했듯이,이 아이디어는 재미 있습니다). 그러나 콜백 호출을 사용하면 일반 이벤트 스택을 사용하지 않을 것입니다. MutationObserver가합니다. – Sebas

+0

아, 내가 무엇을 얻고 있는지 알 겠지만, 별도의 스택 프레임이 무엇이 필요한지 잘 모르겠습니다. 재미는 그렇다하고. – Bergi