[javascript] 3 개의 함수를 차례로 호출하려면 어떻게해야합니까?

이 함수를 하나씩 호출해야하는 경우

$('#art1').animate({'width':'1000px'},1000);
$('#art2').animate({'width':'1000px'},1000);
$('#art3').animate({'width':'1000px'},1000);        

jQuery에서 다음과 같은 작업을 수행 할 수 있다는 것을 알고 있습니다.

$('#art1').animate({'width':'1000px'},1000,'linear',function(){
    $('#art2').animate({'width':'1000px'},1000,'linear',function(){
        $('#art3').animate({'width':'1000px'},1000);
    });
});        

그러나 jQuery를 사용하지 않고 전화를 걸고 싶다고 가정 해 봅시다.

some_3secs_function(some_value);
some_5secs_function(some_value);
some_8secs_function(some_value);        

실행하기 위해이 함수를 호출하고 호출이 some_3secs_function끝난 후 실행 한 다음 some_5secs_function호출이 종료 된 후 호출하는 방법은 some_8secs_function무엇입니까?

최신 정보:

여전히 작동하지 않습니다.

(function(callback){
    $('#art1').animate({'width':'1000px'},1000);
    callback();
})((function(callback2){
    $('#art2').animate({'width':'1000px'},1000);
    callback2();
})(function(){
    $('#art3').animate({'width':'1000px'},1000);
}));

세 애니메이션이 동시에 시작됩니다

내 실수는 어디에?



답변

자바 스크립트에는 동기식비동기식 기능이 있습니다.

동기 함수

Javascript의 대부분의 함수는 동기식입니다. 여러 개의 동기 함수를 연속해서 호출하려는 경우

doSomething();
doSomethingElse();
doSomethingUsefulThisTime();

그들은 순서대로 실행됩니다. 완료 doSomethingElse될 때까지 시작되지 않습니다 doSomething. doSomethingUsefulThisTime, doSomethingElse완료 될 때까지 시작되지 않습니다 .

비동기 함수

그러나 비동기 기능은 서로를 기다리지 않습니다. 함수가 비동기라고 가정 할 때, 위와 동일한 코드 샘플을 보자.

doSomething();
doSomethingElse();
doSomethingUsefulThisTime();

기능은 순서대로 초기화되지만 모두 동시에 실행됩니다. 어느 쪽이 먼저 끝날지 일관되게 예측할 수 없습니다. 실행하는 데 가장 짧은 시간이 걸리는 쪽이 먼저 끝납니다.

그러나 때때로 비동기식 함수가 순서대로 실행되기를 원하고 동기식 함수가 비동기식으로 실행되기를 원할 수도 있습니다. 다행히 콜백 및 타임 아웃이 각각 가능합니다.

콜백

하자 우리가 순서대로 실행하려는 것을 세 비동기 기능을 가지고 있다고 가정 some_3secs_function, some_5secs_function하고 some_8secs_function.

함수는 Javascript에서 인수로 전달 될 수 있으므로 함수가 완료된 후 실행할 콜백으로 함수를 전달할 수 있습니다.

우리가 이런 함수를 만들면

function some_3secs_function(value, callback){
  //do stuff
  callback();
}

다음과 같이 순서대로 호출 할 수 있습니다.

some_3secs_function(some_value, function() {
  some_5secs_function(other_value, function() {
    some_8secs_function(third_value, function() {
      //All three functions have completed, in order.
    });
  });
});

타임 아웃

Javascript에서는 특정 시간 초과 (밀리 초) 후에 함수가 실행되도록 지시 할 수 있습니다. 결과적으로 동기 함수가 비동기 적으로 동작하게 할 수 있습니다.

세 개의 동기 함수가있는 경우 함수를 사용하여 비동기 적으로 실행할 수 setTimeout있습니다.

setTimeout(doSomething, 10);
setTimeout(doSomethingElse, 10);
setTimeout(doSomethingUsefulThisTime, 10);

그러나 이것은 약간 추악하며 DRY 원칙 [wikipedia]을 위반합니다 . 함수 배열과 타임 아웃을 받아들이는 함수를 만들어서 약간 정리할 수 있습니다.

function executeAsynchronously(functions, timeout) {
  for(var i = 0; i < functions.length; i++) {
    setTimeout(functions[i], timeout);
  }
}

다음과 같이 호출 할 수 있습니다.

executeAsynchronously(
    [doSomething, doSomethingElse, doSomethingUsefulThisTime], 10);

요약하면, 비동기식으로 실행하려는 비동기 함수가있는 경우 콜백을 사용하고 비동기식으로 실행하려는 동기 함수가있는 경우 시간 종료를 사용하십시오.


답변

이 답변은 표준 promises의 JavaScript 기능인을 사용합니다 ECMAScript 6. 대상 플랫폼이 지원하지 않으면 promisesPromiseJs로 폴리 필하십시오 .

내 대답은 여기를보십시오 . 애니메이션 을 사용하려면 다른 함수를 실행할 때까지 애니메이션이있는 함수가 끝날 때까지 기다리 십시오 jQuery.

다음은 코드의 모양이 ES6 PromisesjQuery animations입니다.

Promise.resolve($('#art1').animate({ 'width': '1000px' }, 1000).promise()).then(function(){
    return Promise.resolve($('#art2').animate({ 'width': '1000px' }, 1000).promise());
}).then(function(){
    return Promise.resolve($('#art3').animate({ 'width': '1000px' }, 1000).promise());
});

일반 메소드도 래핑 할 수 있습니다 Promises.

new Promise(function(fulfill, reject){
    //do something for 5 seconds
    fulfill(result);
}).then(function(result){
    return new Promise(function(fulfill, reject){
        //do something for 5 seconds
        fulfill(result);
    });
}).then(function(result){
    return new Promise(function(fulfill, reject){
        //do something for 8 seconds
        fulfill(result);
    });
}).then(function(result){
    //do something with the result
});

then방법은 곧만큼 실행 Promise완료. 일반적으로 function전달 된 대상 의 반환 값은 다음 값으로 전달됩니다 then.

그러나 a Promise가 반환되면 다음 then함수는 Promise실행 이 끝날 때까지 기다렸다가 그 결과 (에 전달되는 값 fulfill)를받습니다.


답변

동기 함수 와 비동기 함수 실행 의 차이를 완전히 인식하지 못하는 것 같습니다 .

업데이트에서 제공 한 코드는 각 콜백 함수를 즉시 실행하여 애니메이션을 즉시 시작합니다. 그러나 애니메이션은 비동기 적으로 실행 됩니다. 다음과 같이 작동합니다.

  1. 애니메이션에서 단계 수행
  2. setTimeout다음 애니메이션 단계와 지연을 포함하는 함수로 호출
  3. 시간이 지남
  4. 주어진 콜백 setTimeout이 실행
  5. 1 단계로 돌아가십시오

이것은 애니메이션의 마지막 단계가 완료 될 때까지 계속됩니다. 그 동안 동기 기능이 오래 전에 완료되었습니다. 즉, animate함수 호출에 실제로 3 초가 걸리지 않습니다 . 지연 및 콜백으로 효과가 시뮬레이션됩니다.

필요한 것은 대기열 입니다. 내부적으로 jQuery는 애니메이션을 큐에 넣고 해당 애니메이션이 완료된 후에 만 콜백을 실행 합니다 . 콜백이 다른 애니메이션을 시작하면 효과가 순서대로 실행됩니다.

가장 간단한 경우 이것은 다음과 같습니다.

window.setTimeout(function() {
    alert("!");
    // set another timeout once the first completes
    window.setTimeout(function() {
        alert("!!");
    }, 1000);
}, 3000); // longer, but first

일반적인 비동기 루핑 기능은 다음과 같습니다. 주어진 함수를 순서대로 호출하고 각 함수 사이에 지정된 시간 (초) 동안 기다립니다.

function loop() {
    var args = arguments;
    if (args.length <= 0)
        return;
    (function chain(i) {
        if (i >= args.length || typeof args[i] !== 'function')
            return;
        window.setTimeout(function() {
            args[i]();
            chain(i + 1);
        }, 2000);
    })(0);
}    

용법:

loop(
  function() { alert("sam"); },
  function() { alert("sue"); });

구성 가능한 대기 시간이 걸리거나 즉시 첫 번째 기능을 실행 false하거나 체인 apply의 기능이 반환 되거나 지정된 컨텍스트의 기능 또는 기타 필요한 기능이 실행될 때 실행을 중지하도록 분명히 수정할 수 있습니다.


답변

비동기 라이브러리가이를 수행하는 매우 우아한 방법을 제공 할 것이라고 생각합니다 . 약속과 콜백은 다루기가 약간 어려워 질 수 있지만 비동기는 깔끔한 패턴으로 생각 프로세스를 간소화 할 수 있습니다. 직렬로 함수를 실행하려면 비동기 폭포수 에 넣어야합니다 . 비동기 링고에서 모든 함수는 task일부 인수를 취하는 a라고 하며 callback; 시퀀스에서 다음 함수입니다. 기본 구조는 다음과 같습니다.

async.waterfall([
  // A list of functions
  function(callback){
      // Function no. 1 in sequence
      callback(null, arg);
  },
  function(arg, callback){
      // Function no. 2 in sequence
      callback(null);
  }
],
function(err, results){
   // Optional final callback will get results for all prior functions
});

방금 구조를 간단히 설명하려고했습니다. 자세한 내용 은 워터 폴 가이드 를 참조하십시오.


답변

함수는 콜백 함수를 가져와야 할 때 호출됩니다.

function fone(callback){
...do something...
callback.apply(this,[]);

}

function ftwo(callback){
...do something...
callback.apply(this,[]);
}

다음 사용법은 다음과 같습니다.

fone(function(){
  ftwo(function(){
   ..ftwo done...
  })
});


답변

asec=1000;

setTimeout('some_3secs_function("somevalue")',asec*3);
setTimeout('some_5secs_function("somevalue")',asec*5);
setTimeout('some_8secs_function("somevalue")',asec*8);

여기서는 setTimeout에 대해 자세히 설명하지 않겠습니다.

  • 이 경우 문자열로 실행할 코드를 추가했습니다. 이것은 var를 setTimeout-ed 함수에 전달하는 가장 간단한 방법이지만 순수 주의자가 불평합니다.
  • 따옴표없이 함수 이름을 전달할 수도 있지만 변수는 전달할 수 없습니다.
  • 코드는 setTimeout이 트리거 될 때까지 기다리지 않습니다.
  • 이것은 처음에 머리를 돌리기 어려울 수 있습니다. 이전 시점 때문에 호출 함수에서 변수를 전달하면 시간 초과가 트리거 될 때까지 해당 변수가 더 이상 존재하지 않습니다. 호출 함수가 실행되어 vars gone.
  • 익명의 함수를 사용하여이 문제를 해결하는 것으로 알려져 있지만 더 나은 방법이있을 수 있습니다.

답변

자바 스크립트로 태그를 지정 했으므로 함수 이름이 3, 5 및 8 초이므로 타이머 컨트롤을 사용합니다. 따라서 타이머를 3 초 동안 시작한 다음 첫 번째 전화를 걸고 5 초를 두 번째 전화를 걸고 8 초를 세 번째 전화를 걸고 타이머가 끝나면 타이머를 중지하십시오.

일반적으로 Javascript에서는 함수가 하나씩 실행되는 것이 정확하지만 시간이 초과 된 애니메이션을하려고하는 것처럼 보이기 때문에 타이머가 가장 좋습니다.