계속하기 전에 하나의 기능이 완료될 때까지 기다리는 올바른 방법입니까?
JS기능은 두 가지가 있습니다.한쪽이 다른 한쪽을 호출한다.호출 기능 내에서 다른 사람에게 전화를 걸어 해당 기능이 종료될 때까지 기다렸다가 계속 진행합니다.예를 들어 / 의사 코드:
function firstFunction(){
for(i=0;i<x;i++){
// do something
}
};
function secondFunction(){
firstFunction()
// now wait for firstFunction to finish...
// do something else
};
저는 이 해결책을 생각해 냈지만, 이것이 현명한 방법인지 모르겠습니다.
var isPaused = false;
function firstFunction(){
isPaused = true;
for(i=0;i<x;i++){
// do something
}
isPaused = false;
};
function secondFunction(){
firstFunction()
function waitForIt(){
if (isPaused) {
setTimeout(function(){waitForIt()},100);
} else {
// go do that thing
};
}
};
그게 합법인가요?좀 더 우아한 방법이 없을까요?jQuery로 할까요?
이와 같은 비동기 작업을 처리하는 방법 중 하나는 다음과 같은 콜백 함수를 사용하는 것입니다.
function firstFunction(_callback){
// do some asynchronous work
// and when the asynchronous stuff is complete
_callback();
}
function secondFunction(){
// call first function and pass in a callback function which
// first function runs when it has completed
firstFunction(function() {
console.log('huzzah, I\'m done!');
});
}
@Janaka Pushpakumara의 제안대로 화살표 기능을 사용하여 동일한 기능을 구현할 수 있게 되었습니다.예를 들어 다음과 같습니다.
firstFunction(() => console.log('huzzah, I\'m done!'))
업데이트: 이 답변은 꽤 오래 전에 받았는데, 꼭 업데이트하고 싶습니다.콜백은 전혀 문제가 없지만, 제 경험상 읽기 및 유지보수가 더 어려운 코드를 만드는 경향이 있습니다.그래도 진행 중인 이벤트 등을 파라미터로 사용하는 경우가 있습니다.이 업데이트는 대안을 강조하기 위한 것입니다.
또, 원래의 질문에는 비동기라고 하는 구체적인 언급이 없기 때문에, 누군가 혼란스러워하는 경우, 당신의 함수가 동기하고 있는 경우, 호출시에 차단됩니다.예를 들어 다음과 같습니다.
doSomething()
// the function below will wait until doSomething completes if it is synchronous
doSomethingElse()
함수가 비동기적이라면 비동기적 작업을 처리하는 방법은 비동기적/대기적 작업입니다.예를 들어 다음과 같습니다.
const secondFunction = async () => {
const result = await firstFunction()
// do something else here after firstFunction completes
}
IMO, 비동기/대기 기능은 약속을 직접 사용하는 것보다 코드를 훨씬 읽기 쉽게 만듭니다(대부분).캐치 오류를 처리해야 하는 경우 try/catch와 함께 사용합니다.자세한 내용은http://https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function 를 참조해 주세요.
비동기/대기 사용:
async function firstFunction(){
for(i=0;i<x;i++){
// do something
}
return;
};
그런 다음 다른 함수로 wait를 사용하여 반환을 기다립니다.
async function secondFunction(){
await firstFunction();
// now wait for firstFunction to finish...
// do something else
};
먼저 하나의 함수가 완료되기를 기다리는 우아한 방법은 비동기/대기 함수와 함께 Promise를 사용하는 것입니다.
- 먼저 Promise를 만듭니다.제가 만든 기능은 2초 후에 완성됩니다.나는 사용했다
setTimeout
명령을 실행하는 데 시간이 걸릴 수 있는 상황을 보여주기 위해 사용합니다. - 두 번째 기능에서는 비동기/대기 기능을 사용하여
await
명령을 진행하기 전에 첫 번째 기능을 완료해야 합니다.
예:
//1. Create a new function that returns a promise
function firstFunction() {
return new Promise((resolve, reject) => {
let y = 0
setTimeout(() => {
for (i=0; i<10; i++) {
y++
}
console.log('Loop completed.')
resolve(y)
}, 2000)
})
}
//2. Create an async function
async function secondFunction() {
console.log('Before promise call.')
//3. Await for the first function to complete
const result = await firstFunction()
console.log('Promise resolved: ' + result)
console.log('Next step.')
};
secondFunction()
주의:
말하면 된다.resolve
Promise
가 없는resolve()
예에서는, 는 「」입니다resolved
Promise
「」의 을 사용해 .y
두 번째 기능에서 사용할 수 있습니다.
여기서 중요한 점을 간과하고 있는 것 같습니다.자바스크립트번 요? 가 코드를 alert("Here")
:
var isPaused = false;
function firstFunction(){
isPaused = true;
for(i=0;i<x;i++){
// do something
}
isPaused = false;
};
function secondFunction(){
firstFunction()
alert("Here");
function waitForIt(){
if (isPaused) {
setTimeout(function(){waitForIt()},100);
} else {
// go do that thing
};
}
};
isPaused
"Here" 경보입니다isPaused
되다false
및 「」, 「」의firstFunction
돌아올 것이다.'양보'는 에서는 '양보를 할 수 없기 입니다.for
sloope(루프)// do something
루프가 중단되지 않고 먼저 완전히 완료해야 합니다(자세한 내용은 Javascript 스레드 처리 및 레이스 조건).
코드 렇, , 코드 는 할 수 .firstFunction
콜백 또는 약속을 사용하여 발신자에게 통지합니다.해야 할 for
을 반복하여 하다.if
대신 (JSFIDdle):
function firstFunction()
{
var deferred = $.Deferred();
var i = 0;
var nextStep = function() {
if (i<10) {
// Do something
printOutput("Step: " + i);
i++;
setTimeout(nextStep, 500);
}
else {
deferred.resolve(i);
}
}
nextStep();
return deferred.promise();
}
function secondFunction()
{
var promise = firstFunction();
promise.then(function(result) {
printOutput("Result: " + result);
});
}
1.은 '1.7'을했습니다.yield
키워드를 지정합니다.이를 통해 동기화된 JavaScript 코드 흐름의 비동기 홀을 "펀치"할 수 있습니다(상세 및 예시).단, 현재 발전기에 대한 브라우저 지원은 AFAIK의 Firefox와 Chrome으로 제한됩니다.
왜 아무도 이 간단한 패턴에 대해 언급하지 않았을까?:
(function(next) {
//do something
next()
}(function() {
//do some more
}))
무작정 기다리기 위해 타임아웃을 사용하는 것은 나쁜 관행이며, 약속을 수반하는 것은 코드를 더 복잡하게 만들 뿐입니다.OP의 경우:
(function(next) {
for(i=0;i<x;i++){
// do something
if (i==x-1) next()
}
}(function() {
// now wait for firstFunction to finish...
// do something else
}))
소규모 데모 -> http://jsfiddle.net/5jdeb93r/
약속의 유일한 문제는 IE가 약속을 지원하지 않는다는 것입니다.엣지는 가능하지만 IE 10 및 11은 많이 있습니다.https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise (아래쪽 호환성)
JavaScript는 싱글 스레드입니다.비동기 콜을 발신하지 않는 경우는, 예측 가능한 동작이 됩니다.메인 JavaScript 스레드는 다음 함수를 실행하기 전에 코드에 나타나는 순서대로 하나의 함수를 완전히 실행합니다.동기 함수의 순서를 보증하는 것은 간단하며, 각 함수는 호출된 순서대로 완전히 실행됩니다.
동기 함수는 일의 원자 단위라고 생각하세요.메인 JavaScript 스레드는 명령문이 코드에 나타나는 순서대로 완전히 실행됩니다.
단, 다음과 같이 비동기 콜을 투입합니다.
showLoadingDiv(); // function 1
makeAjaxCall(); // function 2 - contains async ajax call
hideLoadingDiv(); // function 3
이건 네가 원하는 게 아니야기능 1, 기능 2, 기능 3을 즉시 실행합니다.div 플래시를 로드하면 사라집니다. 반면 에이잭스 호출은 거의 완료되지 않았습니다.makeAjaxCall()
가 돌아왔습니다.복잡성은 메인 JavaScript 스레드의 각 스핀에 의해 조금씩 진보된 청크로 작업이 분할된 것입니다.-동시에 동작합니다.그러나 동일한 메인 스레드는 한 번의 스핀/실행 동안 동기 부분을 빠르고 예측 가능하게 실행했습니다.
그래서 제가 다루는 방법: 아까 말했듯이 함수는 일의 원자 단위입니다.함수 1의 코드와 함수2의 코드를 조합하여 비동기 호출 전에 함수1의 코드를 함수2에 넣습니다.기능 1을 제거했습니다.비동기 콜까지를 포함한 모든 것이 예측 가능한 순서로 실행됩니다.
그런 다음 비동기 호출이 완료되면 메인 자바스크립트 스레드를 여러 번 회전시킨 후 함수 3을 호출합니다.이렇게 하면 순서가 보장됩니다.예를 들어 ajax에서는 onreadystatechange 이벤트핸들러가 여러 번 호출됩니다.완료가 보고되면 원하는 최종 기능을 호출합니다.
더 지저분하다는 거 인정해.코드가 대칭인 것, 함수가 한 가지 일을 하는 것(또는 그것에 근접하는 것)을 좋아하는 것, 그리고 어떤 식으로든 (발신자에 대한 의존성을 만드는 것) 표시를 담당하는 것을 좋아하지 않는다.다만, 동기 함수에 비동기 콜이 포함되어 있기 때문에, 실행 순서를 보증하기 위해서 타협이 필요합니다.그리고 IE 10을 코드화해야 하기 때문에 약속은 없습니다.
요약: 동기 콜의 경우 순서를 보증하는 것은 간단합니다.각 함수는 호출된 순서대로 완전히 실행됩니다.비동기 콜이 있는 함수의 경우 순서를 보증하는 유일한 방법은 비동기 콜이 완료되면 감시하고 그 상태가 검출되면 세 번째 함수를 호출하는 것입니다.
JavaScript 스레드에 대한 자세한 내용은http://https://developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop 를 참조해 주세요.https://medium.com/ @script _ rizi / script - main - script - script - script - script - sc85fce7e23
또한 이 주제에 대한 유사한 높은 평가를 받은 또 다른 질문입니다.3개의 함수를 차례로 실행하려면 어떻게 불러야 할까요?
Promise 사용 가능
약속은 미래의 알 수 없는 값을 나타내는 JavaScript 구성입니다.API 호출의 결과일 수도 있고 실패한 네트워크 요청의 오류 개체일 수도 있습니다.당신은 반드시 뭔가를 얻을 수 있습니다.
const promise = new Promise((resolve, reject) => {
// Make a network request
if (yourcondition=="value") {
} else {
reject(error);
}
})
promise.then(res => {
//if not rejected, code
}).catch(err => {
//return false;
})
약속은 가질 수 있다.
완료됨 - 작업이 성공적으로 완료되었습니다.
거부됨 - 액션 실패
보류 중 - 어느 작업도 완료되지 않았습니다.
해결됨 - 완료되었거나 거부됨
의 주요 는 ★★★★★★★★★★★★★★★★★★★★★★★★★★★★」firstFunction
완료하면 다음 기능이 실행됩니다.
async firstFunction() {
const promise = new Promise((resolve, reject) => {
for (let i = 0; i < 5; i++) {
// do something
console.log(i);
if (i == 4) {
resolve(i);
}
}
});
const result = await promise;
}
second() {
this.firstFunction().then( res => {
// third function call do something
console.log('Gajender here');
});
}
저는 이틀 동안 노력한 끝에 이 글을 썼어요.다음과 같이 시도하는 것이 가장 좋습니다.
var recv = -1;
async function First_fn() {
var answ = await Second_fn();
console.log(answ);
recv = -1;
}
async function Second_fn() {
var parm = 1;
var adrss = 2;
await Third_fn(adrss, parm);
// Using the following loop will minimize the waiting time
for (let i = 0; i < 180; i++) {
if (recv !== -1) {
console.log(recv);
break;
}
else {
await new Promise(resolve => setTimeout(resolve, 500));
}
}
return recv;
}
async function Third_fn(adrss, parm) {
//someting to do => result
//for example:
let result = adrss + parm;
recv = result; // recv is global varable
}
First_fn();
여러 작업을 동시에 수행해야 하기 때문에 제가 생각해낸 것입니다.
<button onclick="tprom('Hello Niclas')">test promise</button>
<script>
function tprom(mess) {
console.clear();
var promise = new Promise(function (resolve, reject) {
setTimeout(function () {
resolve(mess);
}, 2000);
});
var promise2 = new Promise(async function (resolve, reject) {
await promise;
setTimeout(function () {
resolve(mess + ' ' + mess);
}, 2000);
});
var promise3 = new Promise(async function (resolve, reject) {
await promise2;
setTimeout(function () {
resolve(mess + ' ' + mess+ ' ' + mess);
}, 2000);
});
promise.then(function (data) {
console.log(data);
});
promise2.then(function (data) {
console.log(data);
});
promise3.then(function (data) {
console.log(data);
});
}
</script>
이거 드셔보세요
function firstFunction(){
// do something
X=true;
return X;
}
function secondFunction(){
X=false;
X=firstFunction();
setTimeout( function() {
if(X==true){
// do something else
}else{
// do something else
}
alert(X); // To check X
}, 100); // Can increase time delay 200,300, ...
}
시간을 100에서 200, 300으로 늘립니다.첫 번째 기능이 완료되기까지 걸리는 시간을 기준으로 합니다.
저도 같은 문제가 있었습니다.
함수의 두인 My Solution을 이었습니다.
함수에 에 For 루프가 .
하면 두 할 수 .
, 그것은 '그것'입니다.
i = x-1이므로:
function firstFunction(){
for(i=0;i<x;i++){
// do something
if(i === x - 1){
// do something else or call secondFunction();
}
}
}
언급URL : https://stackoverflow.com/questions/21518381/proper-way-to-wait-for-one-function-to-finish-before-continuing
'programing' 카테고리의 다른 글
Laravel Archent 쿼리에서 테이블에 별칭을 지정하는 방법(또는 Query Builder 사용) (0) | 2022.10.21 |
---|---|
내가 왜 템플리팅 엔진을 쓰겠어?jsp include 및 jstl vs 타일, 프리마커, 속도, 시트메쉬 (0) | 2022.10.21 |
함수에 전역 변수 사용 (0) | 2022.10.21 |
Google Invisible reCAPTCHA 배지를 숨기는 방법 (0) | 2022.10.20 |
팬더 컬럼의 값을 dict로 다시 매핑하고 NaNs를 보존합니다. (0) | 2022.10.20 |