2017-02-06 2 views
1

다른 솔루션 (jquery는 괜찮습니까?)을 사용하여 더 우아하게 만들 수 있습니까?배열에서 생성 지연 (jquery)을 사용하여 순차 실행

내 경우 중요한 것은 각각의 실행은 이전 실행이 종료 된 경우에만 트리거된다는 것입니다.

seqExe(["item one", "item two", "item three", "item four", "item five"]) 
 

 
function seqExe(corpus) { 
 
    var i = -1, 
 
     len = corpus.length, 
 
     defer = jQuery.Deferred(), 
 
     promise = defer.promise(); 
 

 
    while(++i < len) { 
 
     promise = promise.then((function(item) { 
 
      return function() { 
 
       console.log(item); 
 
       return foo(item); 
 
      } 
 
     }).call(this, corpus[i])); 
 
    } 
 

 
    promise.then(function() { 
 
     console.log("Done"); 
 
    }, function() { 
 
     console.error("Failed"); 
 
    }); 
 

 
    return defer.resolve(); 
 
} 
 

 
function foo(item) { 
 
    var defer = jQuery.Deferred(); 
 
    window.setTimeout(
 
     function() { 
 
      defer.resolve() 
 
      console.log(item); 
 
     }, Math.random() * 2000 + 1000); 
 

 
    return defer.promise(); 
 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>

을 세웠 출력 같아야

item one 
item one 
item two 
item two 
item three 
item three 
item four 
item four 
item five 
item five 
Done 

답변

2

reduce 사용을위한 이상적인 후보이다. 또한 초기의 약속 - 즉시 해결하려면 - 단지 $.when() 될 수 있으며, 시작 reduce 호출의 값이됩니다 (일부 jQuery를 버전

seqExe(["item one", "item two", "item three", "item four", "item five"]) 
 

 
function seqExe(corpus) { 
 
    return corpus.reduce(function (p, item) { 
 
     return p.then(function() { 
 
      console.log(item + ' pending'); 
 
      return foo(item); 
 
     }); 
 
    }, $.when()) 
 
    .then(function(){ 
 
     console.log("Done"); 
 
    }, function(){ 
 
     console.log("Failed"); 
 
    }); 
 
} 
 

 
function foo(item) { 
 
    var defer = new $.Deferred(); 
 
    window.setTimeout(
 
     function() { 
 
      defer.resolve() 
 
      console.log(item + ' resolved'); 
 
     }, Math.random() * 2000 + 1000); 
 
    return defer.promise(); 
 
}
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>

하는 것으로 이것은 2.1.1에서 보았습니다.) then 콜백이 동 기적으로 실행되어 잘못된 출력 순서를 부여합니다. 이것은 jQuery 3에서 수정되었습니다 (위의 스 니펫에 링크 된 3.1.1도 시도했습니다). 여기

는 기본 ES6의 약속 어떻게 할 것입니다 :.

잘못된 출력 순서를 줄 것이다, * 다음 콜백은 동 기적으로 실행됩니다 "에 의해 무슨 뜻 이죠

seqExe(["item one", "item two", "item three", "item four", "item five"]) 
 

 
function seqExe(corpus) { 
 
    return corpus.reduce(function (p, item) { 
 
     return p.then(function() { 
 
      console.log(item + ' pending'); 
 
      return foo(item); 
 
     }); 
 
    }, Promise.resolve()) 
 
    .then(function(){ 
 
     console.log("Done"); 
 
    }, function(){ 
 
     console.log("Failed"); 
 
    }); 
 
} 
 

 
function foo(item) { 
 
    return new Promise(function (resolve) { 
 
     window.setTimeout(function() { 
 
      resolve(); 
 
      console.debug(item + ' resolved'); 
 
     }, Math.random() * 2000 + 1000); 
 
    }); 
 
}

+0

* "? 이것은 이미 완료된 약속, 즉'$ .when()'에서만 일어날 수 있지만 첫 번째'foo()'호출 이후의 모든 것은 묶여 있습니다. – Bergi

+0

@Bergi, 내가 게시 한 발췌 문장에서 3.1.1 대신 jQuery 버전 2.1.1에 연결하면 출력 순서가 변경되었다는 것을 의미했습니다. NB : 두 번째 콘솔을 처음으로 이동했기 때문에 지금 수정했습니다. 문제가 해결 된 후 다시 놓는 것을 잊어 버렸습니다. – trincot

+0

아, 그거. 맞아, 당신은'deferred.resolve()'호출 앞에'console.debug'를 넣어야 할 것입니다. – Bergi