2011-09-01 5 views
10

나는 동적으로 코드 (함수)를 서버에서로드하고 javascript 코드로 실행하여 배열에 저장하고 실행합니다. 이러한 모든 코드 스 니펫은 정확히 한 번 실행해야합니다. psuedocode이 문제는 훨씬 더 복잡하지만 기본적으로 Ajax의 비동기 성격을 다루는 원자 적 자바 스크립트 연산이 있습니까?

function fetch(foo){ 
    if (foo in fooArray){ 
      //Do Nothing 
    else{ 
      //Fetch foo via Ajax and execute foo() 
    } 
} 

같은

에 따라 다음 내가 네는 if (foo in fooArray)을 실행하고 배열에없는 것을 가정한다

fetch('someFunctionName'); 
fetch('someFunctionName'); 
fetch('someFunctionName'); 
fetch('someFunctionName'); 

아래의 명령을 실행하는 경우, 4 명 모두 코드를 가져 와서 실행합니다. 나는 세마포어와 mutexes에 대해 배우는 날을 기억하고있다. 자바 스크립트에는 그런 것들이있다.

+1

Apparantly 히는 jQuery를이 작업을 수행하기 때문에 가능하다 : http://stackoverflow.com/questions/7131991/asynchronous-and-를 동기 조건 – Mchl

+0

나는 그것에 대해 블로그를 작성했습니다 [왜 자바 스크립트에서 동시성 도구가 없습니다] (http://uzairfarooq.github.io/why-no-concurrency-control-tool-in-javascript/) –

+1

링크입니다 깨진, 있어야합니다 : http://blog.uzairfarooq.com/why-no-concurrency-control-tool-in-javascript –

답변

30

JavaScript는 비동기 콜백, 시간 초과, 간격 및 사용자 이벤트와 함께 훌륭하게 작동하지만 아직 동시 처리에 문제가없는 훌륭한 언어입니다. 이는 JavaScript가 기본적으로 단일 스레드이기 때문에 가능합니다. 주어진 코드는 항상 원자 적으로 실행되며 JavaScript를 실행하는 다른 스레드에 의해 중단되지 않습니다.

fetch() 기능은 중단없이 항상 실행됩니다. AJAX 콜백의 일부로 실행되고 여러 AJAX 콜백이 보류중인 경우 대기열에 들어갑니다.

다른 예 : 입력 요소에 이벤트 처리기가 할당되어 있고 한 번에 여러 번 실행하면 이벤트 처리기가 동시에 실행되지 않습니다. 대신 대기열에 넣어서 순차적으로 실행됩니다. 이는 setTimeout()/setInterval()에 의해 트리거 된 여러 이벤트에도 적용됩니다.

보조 노트 : 이것은 node.js이 매우 강력하다는 이유 중 하나입니다. 단일 스레드 만 사용하고 I/O에서는 차단하지 않지만 데이터 준비/이벤트가 발생하면 대신 콜백을 사용합니다.

+5

엄밀히 말하면 [웹 노동자] (http://en.wikipedia.org/wiki/Web_Workers) JS의 동시 실행을 허용하지만 웹 작업자와 "정상적인"JS 간의 유일한 상호 작용은 메시지를 통해 발생하기 때문에 동시성 문제가 발생하지 않습니다. –

+0

토마스 당신이 말하는 것은 고맙습니다. – puk

+0

@ Tomasz, AJAX 호출에 시간이 너무 오래 걸리는 경우 브라우저에 따라 너무 많은 (브라우저에 따라 2 개 또는 6 개가 넘는) 너무 많은 것을 원하지 않을 수도 있으므로 아래의 캐싱 솔루션을 제공합니다. 어떻게 생각하십니까? –

1

자바 스크립트는 기본적으로 단일 스레드이므로 뮤텍스가 필요하지 않습니다. 귀하의 후속 가져 호출 아약스 호출 예 만드는 피할 수 있도록 플래그를 설정할 수 있습니다 가져 오기 :

var beingFetched = {};//map onflight -> callbacks 
function fetch(foo){ 
    if (foo in fooArray){ 
     //Do Nothing 
    } else { 
     if (beingFetched.foo) { //note empty array is truthy 
      //register a callback 
      var callback = function(r){ 
      //anything you need to do wit the return object r 
      //maybe even eval it. 
      }; 
      //the callback would more likely be an argument to fetch itself 
      //or you could use a promise API instead so that you can at your will 
      //register multiple callbacks - for error, for success etc. 
      beingFetched.foo.push(callback); 
     } else { 
      beingFetched.foo = [];//truthy 
      //Fetch foo via Ajax and execute 
      $.ajax("getFoo/"+foo).done(function() { 
       _.each(beingFetched.foo, function(cb){ 
        cb.apply(cb,arguments); 
       }); 
       delete beingFetched.foo; 
      }); 
     } 
    } 
} 
관련 문제