programing

자바스크립트 코드를 *순서대로* 실행하는 방법

telebox 2023. 7. 31. 21:18
반응형

자바스크립트 코드를 *순서대로* 실행하는 방법

좋아요, 그래서 저는 Javascript가 C#이나 PHP가 아니라는 것에 감사하지만, 저는 JS 자체가 아니라 제가 사용하는 Javascript의 문제로 계속 돌아옵니다.

다음과 같은 기능이 기능은 다음과 같습니다.

function updateStatuses(){

showLoader() //show the 'loader.gif' in the UI

updateStatus('cron1'); //performs an ajax request to get the status of something
updateStatus('cron2');
updateStatus('cron3');
updateStatus('cronEmail');
updateStatus('cronHourly');
updateStatus('cronDaily');

hideLoader(); //hide the 'loader.gif' in the UI

}

문제는 코드에서 앞서고 싶은 자바스크립트의 불타는 욕망 때문에 'hideLoader' 기능이 바로 실행되기 때문에 로더가 나타나지 않는다는 것입니다.

이걸 어떻게 고칠 수 있을까요?또는 페이지에 쓰는 순서대로 자바스크립트 함수를 실행하려면 어떻게 해야 하나요...

이 문제는 AJAX가 본질적으로 비동기적이기 때문에 발생합니다.이것은 다음을 의미합니다.updateStatus() 호출은 는 JS에 도달합니다.hideLoader()데이터가 AJAX 요청에서 검색되기 전에.

다을수야합다니해행을 수행해야 .hideLoader()AJAX 통화가 종료되는 이벤트에서.

만약 당신이 AJAX 프로그래밍을 한다면 자바스크립트를 절차적인 것이 아니라 이벤트 기반으로 생각해야 합니다.첫 번째 통화가 완료될 때까지 기다렸다가 두 번째 통화를 실행해야 합니다.이렇게 하는 방법은 첫 번째 콜이 완료될 때 발생하는 콜백에 두 번째 콜을 바인딩하는 것입니다.AJAX 라이브러리의 내부 작동에 대해 자세히 알지 못하면(라이브러리를 사용하고 있기를 바랍니다) 어떻게 하는지 알려드릴 수는 없지만 아마 다음과 같이 보일 것입니다.

showLoader();

  updateStatus('cron1', function() {
    updateStatus('cron2', function() {
      updateStatus('cron3', function() {
        updateStatus('cronEmail', function() {
          updateStatus('cronHourly', function() {
            updateStatus('cronDaily', funciton() { hideLoader(); })
          })
        })
      })
    })
  })
});

그생은각,updateStatus일반 인수와 종료 시 실행할 콜백 함수를 사용합니다.실행할 함수를 전달하는 것이 상당히 일반적인 패턴입니다.onComplete이러한 후크를 제공하는 함수로.

갱신하다

당신이 jQuery를하고 있다면, 은 jQuery에서 읽을 수 있습니다.$.ajax()여기: http://api.jquery.com/jQuery.ajax/

코드는 다음과 같습니다.

function updateStatus(arg) {
  // processing

  $.ajax({
     data : /* something */,
     url  : /* something */
  });

  // processing
}

다음과 같은 방법으로 콜백을 두 번째 매개 변수로 받아들이도록 함수를 수정할 수 있습니다.

function updateStatus(arg, onComplete) {
  $.ajax({
    data : /* something */,
    url  : /* something */,
    complete : onComplete // called when AJAX transaction finishes
  });

}

코드에 이것만 있으면 될 것 같습니다.

async: false,

Ajax의 통화 내용은 다음과 같습니다.

jQuery.ajax({
            type: "GET",
            url: "something.html for example",
            dataType: "html",
            async: false,
            context: document.body,
            success: function(response){

                //do stuff here

            },
            error: function() {
                alert("Sorry, The requested property could not be found.");
            }  
        });

분명히 이 중 일부는 변경할 필요가 있습니다.XML,JSON등을 제외하고는async: false,는 JS 엔진에 성공 호출이 돌아올 때까지 기다렸다가(또는 실패할 때까지) 계속 진행하도록 지시하는 주요 지점입니다.이것에는 단점이 있다는 것을 기억하세요, 그리고 그것은 아약스가 돌아올 때까지 전체 페이지가 응답하지 않는다는 것입니다!!!일반적으로 몇 밀리초 이내에 큰 거래는 아니지만 더 오래 걸릴 수 있습니다.

이것이 정답이고 당신에게 도움이 되기를 바랍니다 :)

우리 프로젝트 중 하나에 비슷한 것이 있는데 카운터를 이용해서 해결했습니다.를 각호에대카늘린경으로 updateStatusAJAX 요청의 응답 기능에서 감소시킵니다(사용 중인 AJAX JavaScript 라이브러리에 따라 다름).

0에 되고 AJAX를 호출할 수 .hideLoader().

여기 샘플이 있습니다.

var loadCounter = 0;

function updateStatuses(){
    updateStatus('cron1'); //performs an ajax request to get the status of something
    updateStatus('cron2');
    updateStatus('cron3');    
    updateStatus('cronEmail');
    updateStatus('cronHourly');
    updateStatus('cronDaily');
}

function updateStatus(what) {
    loadCounter++;

    //perform your AJAX call and set the response method to updateStatusCompleted()
}

function updateStatusCompleted() {
    loadCounter--;
    if (loadCounter <= 0)
        hideLoader(); //hide the 'loader.gif' in the UI
}

이것은 코드의 실행 순서와 관련이 없습니다.

로더 이미지가 표시되지 않는 이유는 기능이 실행되는 동안 UI가 업데이트되지 않기 때문입니다.UI에서 변경을 수행하면 기능을 종료하고 브라우저로 제어 권한을 반환할 때까지 변경 내용이 나타나지 않습니다.

이미지를 설정한 후 시간 초과를 사용하여 나머지 코드를 시작하기 전에 브라우저에서 UI를 업데이트할 수 있습니다.

function updateStatuses(){

  showLoader() //show the 'loader.gif' in the UI

  // start a timeout that will start the rest of the code after the UI updates
  window.setTimeout(function(){
    updateStatus('cron1'); //performs an ajax request to get the status of something
    updateStatus('cron2');
    updateStatus('cron3');
    updateStatus('cronEmail');
    updateStatus('cronHourly');
    updateStatus('cronDaily');

    hideLoader(); //hide the 'loader.gif' in the UI
  },0);
}

코드가 제대로 실행되지 않는 것처럼 보일 수 있는 또 다른 요인이 있습니다.AJAX 요청이 비동기인 경우 이 함수는 응답을 기다리지 않습니다.브라우저가 응답을 수신할 때 응답을 처리하는 기능이 실행됩니다.응답을 수신한 후 로더 이미지를 숨기려면 마지막 응답 핸들러 기능이 실행될 때 이 작업을 수행해야 합니다.응답은 요청을 보낸 순서대로 도착할 필요가 없으므로 마지막 응답이 왔을 때 몇 개의 응답을 얻었는지 계산해야 합니다.

다른 사람들이 지적했듯이 동기식 작업을 수행하지 않을 것입니다.AJAX의 A는 비동기를 수용하는 것을 의미합니다.

sync v/s 비동기에 대한 훌륭한 비유를 말씀드리고 싶습니다.당신은 GWT 포럼의 전체 게시물을 읽을 수 있습니다, 저는 단지 관련 비유를 포함하고 있습니다.

상상해보세요...

여러분은 소파에 앉아서 TV를 보고 있는데, 맥주가 다 떨어졌다는 것을 알고, 배우자에게 술 가게로 달려가 여러분에게 좀 가져다 달라고 부탁합니다.당신의 배우자가 현관문 밖으로 걸어 나가는 것을 보자마자, 당신은 소파에서 일어나 부엌으로 터덜터덜 걸어 들어가 냉장고를 엽니다.놀랍게도, 맥주가 없습니다!

물론 맥주는 없습니다, 당신의 배우자는 아직 주류 판매점에 가는 중입니다.그가 돌아올 때까지 기다려야 맥주를 마실 수 있습니다.

하지만 동기화를 원하신다고요?다시 한번 상상해보세요...

배우자가 문밖으로 걸어나옵니다...이제, 당신 주변의 전 세계가 멈추고, 당신은 숨을 쉬지 않고, 문을 받거나, 그가 당신의 맥주를 가져오기 위해 마을을 가로질러 달리는 동안 당신의 쇼를 끝까지 보지 못합니다.잠시 후 정신을 잃을 때까지 멍하니 앉아있다가 정신을 잃을 때까지... EMT와 배우자에게 둘러싸여 오, 이봐, 맥주 받았어라고 말하는 거야.

동기식 서버 호출을 수행해야 할 때 바로 그렇게 됩니다.

Firebug를 설치한 다음 각 showLoader에 다음과 같은 행을 추가하고 Status를 업데이트한 후 Loader를 숨깁니다.

Console.log("event logged");

콘솔 창에 함수에 대한 호출이 나열되고 순서대로 나열됩니다.문제는 "updateStatus" 메서드가 수행하는 작업이 무엇입니까?

백그라운드 작업을 시작한 다음 다시 시작하므로 백그라운드 작업이 완료되기 전에 로더를 숨기기 위한 호출에 도달할 것입니다.Ajax 라이브러리에 "OnComplete" 또는 "OnFinished" 콜백이 있을 수 있습니다. 여기서 다음 updateStatus를 호출합니다.

updateStatus 호출을 다른 함수로 이동합니다. 새로운 함수를 대상으로 한 호출 setTimeout을 만듭니다.

만약 당신의 Ajax 요청이 비동기적이라면, 당신은 어떤 것이 완료되었는지 추적할 수 있는 무언가가 있어야 합니다.각 콜백 메소드는 자신을 위해 어딘가에 "완료" 플래그를 설정하고 마지막 플래그인지 확인할 수 있습니다. 설정된 경우 hideLoader를 호출합니다.

모든 비동기 요청을 처리하는 가장 좋은 솔루션 중 하나는 '약속'입니다.
Promise 개체는 비동기 작업의 최종 완료(또는 실패)를 나타냅니다.

예:

let myFirstPromise = new Promise((resolve, reject) => {
  // We call resolve(...) when what we were doing asynchronously was successful, and reject(...) when it failed.
  // In this example, we use setTimeout(...) to simulate async code. 
  // In reality, you will probably be using something like XHR or an HTML5 API.
  setTimeout(function(){
    resolve("Success!"); // Yay! Everything went well!
  }, 250);
});  

myFirstPromise.then((successMessage) => {
  // successMessage is whatever we passed in the resolve(...) function above.
  // It doesn't have to be a string, but if it is only a succeed message, it probably will be.
  console.log("Yay! " + successMessage);
});

약속.

3개의 비동기 기능이 있고 순서대로 실행될 것으로 예상되는 경우 다음을 수행합니다.

let FirstPromise = new Promise((resolve, reject) => {
    FirstPromise.resolve("First!");
});
let SecondPromise = new Promise((resolve, reject) => {

});
let ThirdPromise = new Promise((resolve, reject) => {

});
FirstPromise.then((successMessage) => {
  jQuery.ajax({
    type: "type",
    url: "url",
    success: function(response){
        console.log("First! ");
        SecondPromise.resolve("Second!");
    },
    error: function() {
        //handle your error
    }  
  });           
});
SecondPromise.then((successMessage) => {
  jQuery.ajax({
    type: "type",
    url: "url",
    success: function(response){
        console.log("Second! ");
        ThirdPromise.resolve("Third!");
    },
    error: function() {
       //handle your error
    }  
  });    
});
ThirdPromise.then((successMessage) => {
  jQuery.ajax({
    type: "type",
    url: "url",
    success: function(response){
        console.log("Third! ");
    },
    error: function() {
        //handle your error
    }  
  });  
});

이 방법을 사용하면 모든 비동기 작업을 원하는 대로 처리할 수 있습니다.

언급URL : https://stackoverflow.com/questions/2637626/how-do-you-make-javascript-code-execute-in-order

반응형