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);
}));
세 개의 애니메이션이 동시에 시작됩니다.
내 실수는 어디에 있습니까?
자바스크립트에는 동기식과 비동기식이 있습니다.
동기 함수
자바스크립트는 대부분의 함수가 동기화 되어 있습니다.여러 동기화 함수를 연속으로 호출하는 경우
doSomething();
doSomethingElse();
doSomethingUsefulThisTime();
그들은 순서대로 실행할 것입니다.doSomethingElse
까지 시작하지 않을 것입니다.doSomething
완료했습니다.doSomethingUsefulThisTime
, 차례로, 시작하지 않을 것입니다.doSomethingElse
완료했습니다.
비동기 함수
그러나 비동기 함수는 서로를 기다리지 않습니다.위에서 본 것과 같은 코드 샘플을 살펴보도록 하겠습니다. 이번에는 함수들이 비동기적이라고 가정합니다.
doSomething();
doSomethingElse();
doSomethingUsefulThisTime();
함수는 순서대로 초기화되지만, 거의 동시에 실행됩니다.어떤 것이 먼저 끝날지 일관성 있게 예측할 수 없습니다. 실행하는 데 가장 짧은 시간이 걸리는 것이 먼저 끝날 것입니다.
그러나 순서대로 비동기적인 함수가 실행되기를 원할 때도 있고, 비동기적인 함수가 비동기적으로 실행되기를 원할 때도 있습니다.다행히 콜백과 타임아웃으로 가능합니다.
콜백
우리가 순서대로 실행하고자 하는 3개의 비동기 함수가 있다고 가정해 보겠습니다.some_3secs_function
,some_5secs_function
,그리고.some_8secs_function
.
함수는 자바스크립트에서 인수로 전달이 가능하므로, 함수가 완료된 후 실행할 콜백으로 전달이 가능합니다.
우리가 이런 기능들을 만든다면,
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.
});
});
});
타임아웃
자바스크립트에서는 일정 시간 초과(밀리초 단위) 후 실행할 함수를 지정할 수 있습니다.이는 사실상 동기화 함수가 비동기적으로 동작하도록 만들 수 있습니다.
만약 우리가 3개의 동기 함수를 가지고 있다면, 우리는 그것들을 사용하여 비동기적으로 실행할 수 있습니다.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);
요약하면 동기적으로 실행할 비동기 기능이 있는 경우 콜백을 사용하고 비동기적으로 실행할 비동기 기능이 있는 경우 시간 초과를 사용합니다.
이 답변은 의 자바스크립트 기능인 를 사용합니다.ECMAScript 6
표준.대상 플랫폼이 지원하지 않는 경우promises
, PromiseJ로 입력합니다.
여기 내 답변 보기 애니메이션이 포함된 기능이 완료될 때까지 기다리십시오. 사용하려면 다른 기능을 실행하십시오.jQuery
애니메이션, 애니메이션들
코드는 다음과 같습니다.ES6 Promises
그리고.jQuery 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
결과적으로 다음 것으로 전달됩니다.
하지만 만약에Promise
다음이 반환됩니다.then
함수는 다음이 될 때까지 기다립니다.Promise
실행을 완료하고 결과를 수신합니다(다음으로 전달되는 값).fulfill
).
동기식과 비동기식 기능 실행의 차이를 완전히 인식하지 못하고 있는 것 같습니다.
업데이트에서 제공한 코드는 즉시 콜백 기능을 실행하고, 이 기능은 즉시 애니메이션을 시작합니다.그러나 애니메이션은 비동기적으로 실행됩니다.다음과 같이 작동합니다.
- 애니메이션에서 한 단계 수행합니다.
- 불러
setTimeout
다음 애니메이션 단계와 지연을 포함하는 기능으로 - 어느정도 시간이 흐릅니다.
- 에 주어진 콜백.
setTimeout
실행. - 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
특정한 맥락 또는 기타 필요한 모든 기능을 사용할 수 있습니다.
저는 비동기식 라이브러리가 당신에게 매우 우아한 방법을 제공할 것이라고 믿습니다.약속과 콜백은 서로 잘 어울리지 못할 수 있지만, 비동기식은 사고 과정을 능률적으로 처리할 수 있는 깔끔한 패턴을 제공할 수 있습니다.함수를 직렬로 실행하려면 비동기 폭포에 함수를 넣어야 합니다.비동기식에서, 모든 함수는 a라고 불립니다.task
합니다.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...
})
});
javascript로 태그를 해주셨기 때문에, 고객님의 기능명이 3초, 5초, 8초이므로 타이머 컨트롤로 진행하겠습니다.그러면 타이머를 3초만에 시작하고, 첫번째 5초를 호출하고, 세번째를 호출하고, 8초를 호출하고, 끝나면 타이머를 정지합니다.
보통 자바스크립트에서는 기능이 차례로 실행되는 것이 맞지만, 타임 애니메이션을 시도하는 것처럼 보이기 때문에 타이머를 사용하는 것이 최선입니다.
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이 트리거될 때까지 기다리지 않습니다.
- 이것은 처음에는 이해하기 어려울 수 있습니다. 이전 점 때문에 호출 함수에서 변수를 전달하면 해당 변수는 시간 초과가 트리거될 때까지 더 이상 존재하지 않습니다. 호출 함수가 실행되어 변수가 사라집니다.
- 익명의 기능을 이용해 이 모든 것을 해결하는 것으로 알려져 있지만, 더 좋은 방법이 있을 겁니다.
다음과 같은 방법으로 약속을 사용할 수도 있습니다.
some_3secs_function(this.some_value).then(function(){
some_5secs_function(this.some_other_value).then(function(){
some_8secs_function(this.some_other_other_value);
});
});
당신은 당신이 할 수 있는 것입니다.some_value
해 합니다 .
또는 외부 함수에서 내부 함수가 사용하는 값을 다음과 같이 반환할 수 있습니다.
one(some_value).then(function(return_of_one){
two(return_of_one).then(function(return_of_two){
three(return_of_two);
});
});
ES6 업데이트
현재 비동기/대기가 널리 사용되고 있기 때문에 다음과 같은 작업을 수행할 수 있습니다.
async function run(){
await $('#art1').animate({'width':'1000px'},1000,'linear').promise()
await $('#art2').animate({'width':'1000px'},1000,'linear').promise()
await $('#art3').animate({'width':'1000px'},1000,'linear').promise()
}
이것은 기본적으로 기능을 "약속"하고(만약 기능이 아직 비동기식이 아니라면), 그들을 기다리는 것입니다.
//sample01
(function(_){_[0]()})([
function(){$('#art1').animate({'width':'10px'},100,this[1].bind(this))},
function(){$('#art2').animate({'width':'10px'},100,this[2].bind(this))},
function(){$('#art3').animate({'width':'10px'},100)},
])
//sample02
(function(_){_.next=function(){_[++_.i].apply(_,arguments)},_[_.i=0]()})([
function(){$('#art1').animate({'width':'10px'},100,this.next)},
function(){$('#art2').animate({'width':'10px'},100,this.next)},
function(){$('#art3').animate({'width':'10px'},100)},
]);
//sample03
(function(_){_.next=function(){return _[++_.i].bind(_)},_[_.i=0]()})([
function(){$('#art1').animate({'width':'10px'},100,this.next())},
function(){$('#art2').animate({'width':'10px'},100,this.next())},
function(){$('#art3').animate({'width':'10px'},100)},
]);
javascript의 setTimeout을 기반으로 waitTille 기능을 사용합니다.
/*
funcCond : function to call to check whether a condition is true
readyAction : function to call when the condition was true
checkInterval : interval to poll <optional>
timeout : timeout until the setTimeout should stop polling (not 100% accurate. It was accurate enough for my code, but if you need exact milliseconds, please refrain from using Date <optional>
timeoutfunc : function to call on timeout <optional>
*/
function waitUntil(funcCond, readyAction, checkInterval, timeout, timeoutfunc) {
if (checkInterval == null) {
checkInterval = 100; // checkinterval of 100ms by default
}
var start = +new Date(); // use the + to convert it to a number immediatly
if (timeout == null) {
timeout = Number.POSITIVE_INFINITY; // no timeout by default
}
var checkFunc = function() {
var end = +new Date(); // rough timeout estimations by default
if (end-start > timeout) {
if (timeoutfunc){ // if timeout function was defined
timeoutfunc(); // call timeout function
}
} else {
if(funcCond()) { // if condition was met
readyAction(); // perform ready action function
} else {
setTimeout(checkFunc, checkInterval); // else re-iterate
}
}
};
checkFunc(); // start check function initially
};
함수가 특정 조건을 true로 설정하면 폴링을 수행할 수 있습니다.또한 시간 초과 기능과 함께 제공되므로 기능이 작동하지 않을 경우(심지어 시간 범위 내에서도) 대안을 제공할 수 있습니다.사용자 피드백을 생각해 보세요!)
예를 들면
doSomething();
waitUntil(function() { return doSomething_value===1;}, doSomethingElse);
waitUntil(function() { return doSomethingElse_value===1;}, doSomethingUseful);
메모들
날짜로 인해 대략적인 시간 초과 추정치가 발생합니다.정밀도를 높이기 위해 console.time()과 같은 기능으로 전환합니다.Date는 더 큰 크로스 브라우저 및 레거시 지원을 제공합니다.밀리초 단위의 정확한 측정이 필요하지 않은 경우, 브라우저가 지원할 때는 별도로 포장하지 말고 console.time()을 제공합니다.
방법 2, 방법 3, 방법 4 다음에 방법 1을 실행해야 하는 경우.다음 코드 스니펫은 자바스크립트에서 Depended 개체를 사용하여 이를 해결할 수 있습니다.
function method1(){
var dfd = new $.Deferred();
setTimeout(function(){
console.log("Inside Method - 1");
method2(dfd);
}, 5000);
return dfd.promise();
}
function method2(dfd){
setTimeout(function(){
console.log("Inside Method - 2");
method3(dfd);
}, 3000);
}
function method3(dfd){
setTimeout(function(){
console.log("Inside Method - 3");
dfd.resolve();
}, 3000);
}
function method4(){
console.log("Inside Method - 4");
}
var call = method1();
$.when(call).then(function(cb){
method4();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
언급URL : https://stackoverflow.com/questions/5187968/how-should-i-call-3-functions-in-order-to-execute-them-one-after-the-other
'programing' 카테고리의 다른 글
오류 Gypgyp PER를 해결하려면 어떻게 해야 합니까!ERR! 명령줄 또는 npm 구성에서 VSfind VSmsvs_version이 설정되지 않은 VSfind VSmsvs_version을 찾습니까? (0) | 2023.09.19 |
---|---|
안드로이드에서 드로블의 색상을 변경하는 방법은? (0) | 2023.09.19 |
PowerShell에 캐스팅.이상한 구문 (0) | 2023.09.19 |
sscanf에서 읽은 문자 수를 가져오시겠습니까? (0) | 2023.09.19 |
FTP 업로드 및 다운로드 스크립트 방법 (0) | 2023.09.19 |