다음 줄을 실행하기 전에 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.