다음 줄을 실행하기 전에 5 초 정도 기다리십시오.


313

아래의이 기능은 원하는대로 작동하지 않습니다. JS 초보자이기 때문에 이유를 알 수 없습니다.

나는 여부를 확인하기 전에 5 초 기다릴 필요 newState하다 -1.

현재는 기다리지 않고 바로 확인합니다.

function stateChange(newState) {
  setTimeout('', 5000);

  if(newState == -1) {
    alert('VIDEO HAS STOPPED');
  }
}

답변:


323

제공하는 콜백 함수에 코드를 넣어야합니다 setTimeout.

function stateChange(newState) {
    setTimeout(function () {
        if (newState == -1) {
            alert('VIDEO HAS STOPPED');
        }
    }, 5000);
}

다른 코드는 즉시 실행됩니다.


4
주요 문제는 경우에 따라 (특히 테스트) 이것이 부적절하다는 것입니다. 느린 비동기 http 요청 을 시뮬레이션하기 위해 함수에서 복귀하기 전에 500ms 동안 절전 모드를 해제해야하는 경우 어떻게해야 합니까?
— A.Grandt

14
"테스트"가 단위 테스트를 의미하는 경우 테스트 프레임 워크에 비동기 테스트를 실행할 수있는 방법이 있어야합니다. 수동 테스트를 의미하는 경우 : Chrome의 네트워크 탭에는 느린 요청을 시뮬레이트하기위한 조절 드롭 다운이 있습니다.
— Joseph Silber

1
크롬 확장 프로그램을 개발하고 주입 된 스크립트에서 마지막으로 평가 된 값이 결과를 제공해야하는 경우 그리고 약간의 지연이 필요합니까?
— mirek

184

당신은 정말로 이것을해서는 안됩니다. 시간 초과의 올바른 사용은 OP의 문제에 대한 올바른 도구이며 일정 기간 후에 무언가를 실행하려는 다른 경우입니다. 조셉 Silber는 그의 대답에서 그것을 잘 보여주었습니다. 일부 비 생산의 경우에 당신이 경우에는 정말 시간 동안 메인 스레드를 중지하려면,이 그것을 할 것입니다.

function wait(ms){
   var start = new Date().getTime();
   var end = start;
   while(end < start + ms) {
     end = new Date().getTime();
  }
}

다음과 같은 형식으로 실행합니다.

console.log('before');
wait(7000);  //7 seconds in milliseconds
console.log('after');

장기 실행 차단 작업 (예 : 비싼 DOM 조작) 주위의 비동기 작업 혼합을 시퀀싱하기위한 간단한 테스트 사례를 작성했기 때문에 여기에 도착했습니다. 이것은 시뮬레이션 된 차단 작업입니다. 그것은 그 일에 잘 어울리므로 비슷한 유스 케이스로 여기에 도착하는 다른 사람을 위해 게시했다고 생각했습니다. 그럼에도 불구하고 while 루프에서 Date () 객체를 생성하므로 GC가 충분히 오래 실행되면 GC를 압도 할 수 있습니다. 그러나 강조 할 수는 없습니다. 이것은 테스트에만 적합하며, Joseph Silber의 답변을 참조해야하는 실제 기능을 구축하기위한 것입니다.


7
이것은 자바 스크립트 실행을 멈추지 않습니다.
— Terry Lin

23
@TerryLin 실행 해보십시오.
— Mic

6
따라서 기본적으로 CPU 시간을 낭비하고 있습니다. 메인 프로세서가 다른 작업에 집중할 수 있도록 스레드를 절전 모드로 전환하지 않기 때문에 기다리지 않습니다.
— Kyordhel

6
@Gzork Thread sleep은 대기 기능을 구현하는 한 가지 방법 일 뿐이며 불행히도 클라이언트 측 자바 스크립트의 컨텍스트에서는 사용할 수 없습니다. 그러나 클라이언트에서 다른 비동기 작업이 실행되는 동안 완료 될 것이라고 생각한다면 테스트하지 않은 것입니다. 메인 스레드에서 사용하지만 처음에 setTimeout을 통해 호출하더라도 어떻게 다른 비동기 이벤트 jsfiddle.net/souv51v3/1을 중단 시키는지를 보여주는 바이올린을 모았 습니다. JSFiddle 창 자체는 완료되는 동안 응답하지 않습니다.
— Mic

1
끔찍한 해결책 올바른 잠자기 방법은 async / await ala이 답변 stackoverflow.com/questions/951021/… 또는 Etienne 's 를 이용하는 것 입니다.
— David Simic

162

다음은 새로운 async / await 구문을 사용하는 솔루션 입니다.

ECMAScript 6에 도입 된 새로운 기능이므로 브라우저 지원 을 확인하십시오 .

유틸리티 기능 :

const delay = ms => new Promise(res => setTimeout(res, ms));

용법:

const yourFunction = async () => {
  await delay(5000);
  console.log("Waited 5s");

  await delay(5000);
  console.log("Waited an additional 5s");
};

이 방법의 장점은 코드가 동기 코드처럼 보이고 동작하게한다는 것입니다.


ECMAScript 6 필요 없음 : 이미 비동기 로딩을 수행하기 위해 약속을 사용하고 있고 오랜 시간이 걸리는 체인의 일부를 모방하려는 경우이 wait () 함수를 체인에 추가 할 수 있습니다.
— Dovev Hefetz

2
이것은 실제로 새로운 구문으로 가장 좋은 대답입니다. 위의 wait () 솔루션 사용에 문제가있었습니다.
— pianoman102


36

자바 스크립트에서 5 초 동안 일시 중지하려고해서는 안됩니다. 그런 식으로 작동하지 않습니다. 지금부터 5 초 동안 실행되도록 코드 기능을 예약 할 수 있지만 나중에 실행하려는 코드를 기능에 넣어야하며 해당 기능 이후의 나머지 코드는 즉시 계속 실행됩니다.

예를 들면 다음과 같습니다.

function stateChange(newState) {
    setTimeout(function(){
        if(newState == -1){alert('VIDEO HAS STOPPED');}
    }, 5000);
}

그러나 다음과 같은 코드가 있다면 :

stateChange(-1);
console.log("Hello");

console.log()문은 즉시 실행됩니다. stateChange()함수 에서 타임 아웃이 시작될 때까지 기다리지 않습니다 . 미리 정해진 시간 동안 자바 스크립트 실행을 일시 중지 할 수 없습니다.

대신 지연을 실행하려는 모든 코드는 setTimeout()콜백 함수 내에 있거나 해당 함수에서 호출 되어야합니다 .

루핑하여 "일시 정지"하려고한다면, 자바 스크립트 인터프리터를 일정 기간 동안 "매달려"놓아야합니다. Javascript는 단일 스레드에서만 코드를 실행하기 때문에 루핑 할 때 다른 것을 실행할 수 없습니다 (다른 이벤트 핸들러를 호출 할 수 없음). 따라서 변수를 변경하기 위해 다른 코드를 실행할 수 없으므로 일부 변수가 변경되기를 기다리는 루핑은 작동하지 않습니다.


31
미리 정해진 시간 동안 자바 스크립트 실행을 일시 중지 할 수 없습니다 . 나는 당신이 있기 때문에 당신이, 당신이해야하지 의미 생각 할 수 있습니다 (자신을 중지하려는 경우) :var t = new Date().getTime(); while (new Date().getTime() < t + millisecondsToLockupBrowser);
— 조셉 실버

9
@JosephSilber-좋아, 그렇게 할 수는 있지만 실제로는 많은 브라우저에서 작동하지 않으므로 스크립트가 응답하지 않고 끔찍한 사용자 경험이며 배터리 수명이 나쁘고 페이지가 잘못되었다는 대화 상자를 표시합니다. 그렇게하면서 매달리고 ... 나쁘다.
— jfriend00

12
음 물론 끔찍한 될 것이라고, 아무도해야 어느 어느 어느 어느 어느 이제까지 그렇게하지 않습니다. 나는 단지 내면의 "실제로" 저항 할 수 없었다 . 죄송합니다.
— Joseph Silber

31

비동기 기능 을 사용 하는 경우 한 줄로 간단하게 수행 할 수 있습니다.

console.log(1);
await new Promise(resolve => setTimeout(resolve, 3000)); // 3 sec
console.log(2);

주의 대상이 NodeJS 인 경우, (이 미리 정의 된 promisified에서는 setTimeout 함수의)이을 사용하는 것이 더 효율적입니다 :

await setTimeout[Object.getOwnPropertySymbols(setTimeout)[0]](3000) // 3 sec

두 구현의 차이점은 무엇입니까?
— EAzevedo

1
현재는 차이가 없습니다. 그러나 어떤 시점에서 노드가 더 빠르고 안전하고 효율적으로하기로 결정하면 node js 버전을 미리 사용하게됩니다. readabilty가 대부분의 사람들에게 핵심 요소가 될 가능성이 높지만이 경우 첫 번째 방법을 사용하는 것이 좋습니다.
— Shl

감사합니다. 귀하의 답변으로 이미 3 일 동안 직면 한 문제가 해결되었습니다. 감사.
— EAzevedo

8

이 시도:

//the code will execute in 1 3 5 7 9 seconds later
function exec() {
    for(var i=0;i<5;i++) {
        setTimeout(function() {
            console.log(new Date());   //It's you code
        },(i+i+1)*1000);
    }
}

7

밀리 초 단위로 대기하는 이와 같은 함수를 만드는 가장 좋은 방법은이 함수가 인수에 제공된 밀리 초 동안 대기하는 것입니다.

function waitSeconds(iMilliSeconds) {
    var counter= 0
        , start = new Date().getTime()
        , end = 0;
    while (counter < iMilliSeconds) {
        end = new Date().getTime();
        counter = end - start;
    }
}


3

Joseph Silber의 답변을 바탕으로 , 나는 좀 더 일반적인 방식으로 그렇게 할 것입니다.

당신은 당신의 기능을 가질 것입니다 (질문에 따라 하나를 만들어 봅시다) :

function videoStopped(newState){
   if (newState == -1) {
       alert('VIDEO HAS STOPPED');
   }
}

그리고 당신은 대기 기능을 가질 수 있습니다 :

function wait(milliseconds, foo, arg){
    setTimeout(function () {
        foo(arg); // will be executed after the specified time
    }, milliseconds);
}

결국 당신은 가질 것입니다 :

wait(5000, videoStopped, newState);

그것은 해결책입니다. 대신 대기 함수에 인수를 사용하지 않고 ( foo();대신 대신 foo(arg);) 인수를 사용 하지만 그 예입니다.


3

이 솔루션은 새로 고침 제어에 대한 React Native의 문서 에서 제공됩니다 .

function wait(timeout) {
    return new Promise(resolve => {
        setTimeout(resolve, timeout);
    });
}

이것을 OP의 질문에 적용하기 위해이 기능을 다음과 함께 사용할 수 있습니다 await.

await wait(5000);
if (newState == -1) {
    alert('Done');
}

1

함수를 약간 변경하여 지연을 추가 할 수 있습니다 (async 및 await).

const add5SecondsDelay = () => {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve('5 seconds');
    }, 50000);
  });
}

async function asyncFunctionCall() {

  console.log("stpe-1"); 
  const result = await add5SecondsDelay ();
  console.log("step-2 after 5 seconds delay"); 

}

asyncFunctionCall();

-2

angularjs를 사용하여 :

$timeout(function(){
if(yourvariable===-1){
doSomeThingAfter5Seconds();
}
},5000)

-2

새로운 JS 기능 생성

function sleep(delay) {
        var start = new Date().getTime();
        while (new Date().getTime() < start + delay);
      }

실행을 늦출 때 함수를 호출하십시오. 지연 값으로 밀리 초를 int 단위로 사용하십시오.

####Some code
 sleep(1000);
####Next line

3
너무 많은 자원을 소비합니다.
— awavi 2016 년

-2

Edge 또는 IE에서 PC 게임을 실행하는 데 사용했습니다. 그리고 7 초 후에 IE Edge를 자동으로 닫습니다.

Firefox와 Chrome은 이런 방식으로 게임을 시작하는 데 사용할 수 없습니다.

<html<body>
<a href="E:\game\game.exe" name="game" onmouseout="waitclose(7000);"> game
<img src="game.jpg" width="100%" height="97%" ></a>
<script>
function waitclose(ms){
 var start = new Date().getTime();var end=start;
 while(end < start + ms) {end = new Date().getTime();}
window.open('', '_self', ''); window.close();
}
</script>
</body></html>
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.