2017-10-27 6 views
0

여기 여러 JS 파일을 순차적으로로드하려고합니다. $.when의 문제는 체인이 완료 될 때까지 기다리지 않습니다. 그러나 마지막으로 $.Deferred.then은 예상대로 작동합니다. $.when을 작동하게하려면 어떻게해야합니까?

var urls = [ 
 
    "https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.js", 
 
    "https://cdnjs.cloudflare.com/ajax/libs/photoswipe/4.1.2/photoswipe.js", 
 
    "https://cdnjs.cloudflare.com/ajax/libs/photoswipe/4.1.2/photoswipe-ui-default.js" 
 
]; 
 
var xxx = $.Deferred(); 
 
xxx.then(function() { 
 
     options = { 
 
      dataType: "script", 
 
      url: urls[0], 
 
      cache: false 
 
     }; 
 
     return $.ajax(options).promise(); 
 
    }) 
 
    .then(function() { 
 
     options = { 
 
      dataType: "script", 
 
      url: urls[1], 
 
      cache: false 
 
     }; 
 
     return $.ajax(options).promise(); 
 
    }) 
 
    .then(function() { 
 
     options = { 
 
      dataType: "script", 
 
      url: urls[2], 
 
      cache: false 
 
     }; 
 
     return $.ajax(options).promise(); 
 
    }).then(function() { 
 
     $("body").append("This is correct. All files are loaded.<br>"); 
 
    }); 
 

 
$.when(xxx).done(function() { 
 
    $("body").append("This is wrong. JS files are not loaded yet.<br>"); 
 
}); 
 
xxx.resolve();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>

바이올린 https://jsfiddle.net/ergec/fmrj6qgp/

+0

당신은'$의 .when'를 사용하려는 이유는 다음 예상대로'$ .Deferred.then'와 함께 작동하면? –

+0

여기서'$ .when()'또는'$ .Deferred()'를 사용할 이유가 없습니다. '$ .ajax (...), then()'으로 체인을 시작하십시오. 마지막'.then()'핸들러는 전체 체인이 언제 완료되었는지를 잘 알고 있어야합니다. 반환'$ .ajax (...)'가 잘 작동하면'return $ .ajax(). promise()'를 사용할 이유가 없습니다. – jfriend00

답변

1

같은 약속 떨어져 두 가지를 만들 수 있기 때문에 귀하의 방법은 작동하지 않습니다.

var xxx = $.Deferred(); 
xxx.then(...).then(...);  // promise chain 1 
xxx.then(...)    // promise chain 2 
xxx.resolve();    // start the race between the two promise chains 

이는 두 개의 서로 다른 약속 체인 사이의 단순한 서열이며 순서가 지정되거나 조정되지 않습니다. 어느 것이 든 실행할 시간이 적어지면 먼저 끝나야합니다. 그들 사이에 제로 조정이 있습니다.

자세한 설명은 Chaining vs. Branchingp.then().then() vs. p.then(); p.then()을 참조하십시오.

그리고 $.when(xxx).done()을 사용하면 불필요하며 전혀 문제가되지 않습니다. xxx.done()과 동일한 결과가 나타납니다.


당신은 하나의 약속 체인을 사용하여 문제를 해결할 수 :

p.then(...).then(...).then(...) 

는 그런 모든 것이 제대로 서열 및 조정됩니다.

var urls = [ 
    "https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.js", 
    "https://cdnjs.cloudflare.com/ajax/libs/photoswipe/4.1.2/photoswipe.js", 
    "https://cdnjs.cloudflare.com/ajax/libs/photoswipe/4.1.2/photoswipe-ui-default.js" 
]; 
let options = { 
    dataType: "script", 
    url: urls[0], 
    cache: false 
}; 
$.ajax(options).then(function() { 
    let options = { 
     dataType: "script", 
     url: urls[1], 
     cache: false 
    }; 
    return $.ajax(options); 
}).then(function() { 
    let options = { 
     dataType: "script", 
     url: urls[2], 
     cache: false 
    }; 
    return $.ajax(options).then(function() { 
      $("body").append("Last script loaded<br>"); 
    }); 
}).then(function() { 
     $("body").append("This is correct. All files are loaded.<br>"); 
}); 

근무 예 : 당신은 아직도 당신이 나중에 xxx.resolve()으로 시작할 수 var xxx = $.Deferred()으로 체인을 초기화하기를 원한다면 https://jsfiddle.net/jfriend00/tLp68a3q/


또는, 당신도 그렇게 할 수 있지만, 당신이 할 수있는 ' xxx.then() 또는 $.when(xxx)을 사용하십시오. 이는 다른 약속 체인과 전혀 연결되지 않은 완전히 별개의 분기이기 때문입니다.

작업을 예를 $.Deferred()로 시작 : https://jsfiddle.net/jfriend00/y5n3hb99/