development

Node.js (자바 스크립트)에서 어떻게 기다릴 수 있습니까?

big-blog 2020. 3. 17. 23:39
반응형

Node.js (자바 스크립트)에서 어떻게 기다릴 수 있습니까?


개인의 요구에 맞는 스크립트와 같은 콘솔을 개발 중입니다. 오랜 시간 동안 일시 중지 할 수 있어야하지만 내 연구에서 node.js는 필요에 따라 중지 할 수 없습니다. 일정 기간이 지나면 사용자 정보를 읽기가 어려워지고 있습니다. 코드가 몇 개 있지만, 내부에 다른 코드가 있어야 다음과 같은 작업을 수행 할 수 있습니다.

setTimeout(function() {
}, 3000);

그러나 일정 기간이 지나면이 코드 줄 뒤의 모든 것이 실행되어야합니다.

예를 들어

//start-of-code
console.log('Welcome to My Console,');
some-wait-code-here-for-ten-seconds..........
console.log('Blah blah blah blah extra-blah');
//endcode. 

나는 또한 같은 것들을 보았다

yield sleep(2000);

그러나 node.js는 이것을 인식하지 못합니다.

이 연장 된 일시 정지를 어떻게 달성 할 수 있습니까?


이를 수행하는 가장 좋은 방법은 다음과 같이 코드를 여러 함수로 나누는 것입니다.

function function1() {
    // stuff you want to happen right away
    console.log('Welcome to My Console,');
}

function function2() {
    // all the stuff you want to happen after that pause
    console.log('Blah blah blah blah extra-blah');
}

// call the first chunk of code right away
function1();

// call the rest of the code and have it execute after 3 seconds
setTimeout(function2, 3000);

JohnnyHK 의 솔루션 과 비슷 하지만 훨씬 깔끔하고 확장하기 쉽습니다.


오래된 질문에 대한 새로운 답변. 오늘 ( 2017 년 1 월 6 월 2019) 훨씬 쉽습니다. 새로운 async/await구문을 사용할 수 있습니다 . 예를 들면 다음과 같습니다.

async function init(){
   console.log(1)
   await sleep(1000)
   console.log(2)
}
function sleep(ms){
    return new Promise(resolve=>{
        setTimeout(resolve,ms)
    })
}

사용하기 위해 async/await설치 및 플러그인없이 상자 밖으로, 당신은 사용하여 노드-V7 또는 노드-V8을 사용할 필요가 --harmony플래그를.

2019 년 6 월 업데이트 : 최신 버전의 NodeJS를 사용하면 즉시 사용할 수 있습니다. 명령 줄 인수를 제공 할 필요가 없습니다. 오늘날에도 Chrome에서도 지원합니다.

더 많은 정보:


setTimeout콜백 내에 지연 후 실행하려는 코드를 넣으십시오 .

console.log('Welcome to My Console,');
setTimeout(function() {
    console.log('Blah blah blah blah extra-blah');
}, 3000);

이것은 간단한 차단 기술입니다.

var waitTill = new Date(new Date().getTime() + seconds * 1000);
while(waitTill > new Date()){}

그건 차단 다른 것도 (콜백 같은) 스크립트에서 일어날 것 인 한. 그러나 이것은 콘솔 스크립트이므로 필요한 것일 수 있습니다!


의존성이없는 가장 짧은 솔루션 :

await new Promise(done => setTimeout(done, 5000));

현대적인 자바 스크립트를 사용한 단순하고 우아한 수면 기능

function sleep(millis) {
    return new Promise(resolve => setTimeout(resolve, millis));
}

의존성, 콜백 지옥 없음; 그게 다야 :-)


질문에 주어진 예를 고려할 때 두 콘솔 로그 사이에서 잠을 자게됩니다.

async function main() {
    console.log("Foo");
    await sleep(2000);
    console.log("Bar");
}

main();

"단점"은 이제 주요 기능 async도 마찬가지라는 것입니다. 그러나 현대 Javascript 코드를 이미 작성하고 있다고 생각하면 코드 전체에서 async/를 사용하고 있거나 적어도 await문제가되지 않으므로 실제로는 문제가되지 않습니다. 오늘날 모든 최신 브라우저가 이를 지원 합니다.

팻 화살표 연산자에 sleep익숙하지 않은 사람들을 위해 함수에 대한 약간의 통찰력을 제공하는 async/await이것은 이것을 작성하는 자세한 방법입니다.

function sleep(millis) {
    return new Promise(function (resolve, reject) {
        setTimeout(function () { resolve(); }, millis);
    });
}

그러나 팻 화살표 연산자를 사용하면 더 작고 우아합니다.


www.npmjs.com/package/sleep을 사용할 수 있습니다

var sleep = require('sleep');
sleep.sleep(10); // sleep for ten seconds

노드 7.6.0 이상에서

노드는 기본적으로 대기를 지원합니다.

const sleep = (waitTimeInMs) => new Promise(resolve => setTimeout(resolve, waitTimeInMs));

그런 다음 비동기 기능을 사용할 수 있다면 :

await sleep(10000); // sleep for 10 seconds

또는:

sleep(10000).then(() => {
  // This will execute 10 seconds from now
});

이전 노드 버전 (원래 답변)

CPU가 오래 걸리지 않고 Windows 및 Linux에서 작동하는 비동기 절전 모드가 필요했습니다. 절전 패키지를 시도했지만 Windows 상자에 설치되지 않았습니다. 나는 다음을 사용하여 끝났다.

https://www.npmjs.com/package/system-sleep

설치하려면 다음을 입력하십시오.

npm install system-sleep

귀하의 코드에서

var sleep = require('system-sleep');
sleep(10*1000); // sleep for 10 seconds

매력처럼 작동합니다.


이 질문은 상당히 오래되었지만 최근 V8에는 OP가 요청한 것을 수행 할 수있는 생성기가 추가되었습니다. 생성기는 일반적으로 suspend 또는 gen-run 과 같은 라이브러리의 도움으로 비동기식 상호 작용에 사용하기 가장 쉽습니다 .

다음은 suspend를 사용하는 예입니다.

suspend(function* () {
    console.log('Welcome to My Console,');
    yield setTimeout(suspend.resume(), 10000); // 10 seconds pass..
    console.log('Blah blah blah blah extra-blah');
})();

관련 독서 (부끄러운 자기 진흥을 통한) : 제너레이터와의 큰 거래는 무엇입니까? .


Linux / nodejs에서 이것은 나를 위해 작동합니다.

const spawnSync = require ( 'child_process'). spawnSync;

var sleep = spawnSync ( '수면', [1.5]);

차단 중이지만 통화 중 대기 루프가 아닙니다.

지정하는 시간은 초 단위이지만 분수 일 수 있습니다. 다른 OS와 비슷한 명령이 있는지 모르겠습니다.


최근에 wait.for 라는 간단한 추상화를 만들어 동기화 모드 (노드 광섬유 기반)에서 비동기 함수를 호출했습니다. 다가오는 ES6 Generator를 기반으로하는 버전도 있습니다.

https://github.com/luciotato/waitfor

wait.for를 사용하면 노드의 이벤트 루프를 차단하지 않고 표준 nodejs 비동기 함수를 동기화 함수처럼 호출 할 수 있습니다.

필요할 때 순차적으로 코딩 할 수 있습니다. 즉, 개인적 사용을 위해 스크립트를 단순화하는 데 완벽합니다.

사용 뭘요 코드하는 것입니다 :

require('waitfor')

..in a fiber..
//start-of-code
console.log('Welcome to My Console,');
wait.miliseconds(10*1000); //defined in waitfor/paralell-tests.js - DOES NOT BLOCK
console.log('Blah blah blah blah extra-blah');
//endcode. 

또한 모든 비동기 함수는 동기화 모드 에서 호출 될 수 있습니다 . 예제를 확인하십시오.


"골프 코딩"을 원한다면 여기에 다른 답변 중 더 짧은 버전을 만들 수 있습니다.

const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));

그러나 실제로 제 생각에 이상적인 대답은 Node의 util라이브러리와 그 promisify기능 을 사용하는 것입니다.이 라이브러리 는 정확히 이런 종류의 것을 위해 설계되었습니다 (기존의 비 약속 기반의 약속 기반 버전 만들기).

const util = require('util');
const sleep = util.promisify(setTimeout);

두 경우 모두 다음을 사용 await하여 sleep함수 를 호출하여 간단히 일시 중지 할 수 있습니다 .

await sleep(1000); // sleep for 1s/1000ms

javascript 엔진 (v8)은 이벤트 큐의 이벤트 순서에 따라 코드를 실행하므로 지정된 시간 이후에 javascript가 정확하게 실행을 트리거하는 것은 엄격하지 않습니다. 즉, 나중에 코드를 실행하기 위해 몇 초를 설정하면 트리거링 코드는 순전히 이벤트 큐의 시퀀스를 기반으로합니다. 따라서 코드 실행을 트리거하는 데 지정된 시간보다 오래 걸릴 수 있습니다.

따라서 Node.js는 다음과 같습니다.

process.nextTick()

나중에 setTimeout () 대신 코드를 실행하십시오. 예를 들어

process.nextTick(function(){
    console.log("This will be printed later");
});

ES6 지원을 통해 Promise타사 지원없이 사용할 수 있습니다.

const sleep = (seconds) => {
    return new Promise((resolve, reject) => {
        setTimeout(resolve, (seconds * 1000));
    });
};

// We are not using `reject` anywhere, but it is good to
// stick to standard signature.

그런 다음 다음과 같이 사용하십시오.

const waitThenDo(howLong, doWhat) => {
    return sleep(howLong).then(doWhat);
};

점을 유의 doWhat함수가된다 resolve내에서 콜백 new Promise(...).

또한 이것은 비동기 수면입니다. 이벤트 루프를 차단하지 않습니다. 차단 수면이 필요한 경우 C ++ 바인딩의 도움으로 차단 수면을 실현하는이 라이브러리를 사용하십시오. (비동기 환경과 같은 노드에서 블로킹 절전이 필요한 경우는 드 rare니다.)

https://github.com/erikdubbelboer/node-sleep


let co = require('co');
const sleep = ms => new Promise(res => setTimeout(res, ms));

co(function*() {
    console.log('Welcome to My Console,');
    yield sleep(3000);
    console.log('Blah blah blah blah extra-blah');
});

위의 코드는 자바 스크립트의 비동기 콜백 지옥 문제 해결의 부작용입니다. 이것이 또한 자바 스크립트를 백엔드에서 유용한 언어로 만드는 이유이기도합니다. 실제로 이것은 현대 자바 스크립트에 도입 된 가장 흥미로운 개선 사항입니다. 작동 방식을 완전히 이해하려면 생성기 작동 방식을 완전히 이해해야합니다. functiona로 다음 키워드는 *현대 자바 스크립트의 생성 기능이라고합니다. npm 패키지 co는 생성기를 실행하기위한 러너 기능을 제공했습니다.

본질적으로 생성기 함수는 생성기 함수 yield에서 키워드 를 사용하여 함수의 실행을 일시 중지하는 방법을 제공 yield했으며 생성기 내부와 호출자 사이에서 정보를 교환 할 수있게했습니다. 이는 호출자가 promise비동기 호출에서 데이터를 추출 하고 확인 된 데이터를 생성기로 다시 전달 하는 메커니즘을 제공했습니다 . 효과적으로 비동기 호출을 동 기적으로 만듭니다.


이것은 @ atlex2가 제안한 더티 차단 접근 방식 에 기반한 moment.js 특징 모듈 입니다. 테스트 용으로 만 사용하십시오 .

const moment = require('moment');

let sleep = (secondsToSleep = 1) => {
    let sleepUntill = moment().add(secondsToSleep, 'seconds');
    while(moment().isBefore(sleepUntill)) { /* block the process */ }
}

module.exports = sleep;

테스트 목적으로 일시 중단 해야하는 경우 현재 스레드 실행을 시도하십시오.

function longExecFunc(callback, count) {

    for (var j = 0; j < count; j++) {
        for (var i = 1; i < (1 << 30); i++) {
            var q = Math.sqrt(1 << 30);
        }
    }
    callback();
}
longExecFunc(() => { console.log('done!')}, 5); //5, 6 ... whatever. Higher -- longer

간단하게 우리는 어떤 이벤트가 발생할 때 (코드의 다른 곳에서 done 변수가 true로 설정되어 있음) 또는 시간 초과가 만료 될 때마다 5 초 동안 기다릴 것입니다.

    var timeout=5000; //will wait for 5 seconds or untildone
    var scope = this; //bind this to scope variable
    (function() {
        if (timeout<=0 || scope.done) //timeout expired or done
        {
            scope.callback();//some function to call after we are done
        }
        else
        {
            setTimeout(arguments.callee,100) //call itself again until done
            timeout -= 100;
        }
    })();

일부 사람들은 허용 된 답변이 작동하지 않고 다른 답변을 찾았으며 나 에게 도움이되었습니다 .setTimeout () 콜백에 매개 변수를 전달하는 방법은 무엇입니까?

var hello = "Hello World";
setTimeout(alert, 1000, hello); 

'hello'는 전달되는 매개 변수입니다. 시간 종료 시간 후에 모든 매개 변수를 전달할 수 있습니다. 답을 주신 @Fabio Phms에게 감사합니다.


readline-sync를보십시오 ( https://www.npmjs.com/package/readline-sync )

함께 설치 npm install readline-sync

var readlineSync = require('readline-sync');
while(true) {
  var input = readlineSync.question("What is your input?");
  if(input === 'exit') {
    process.exit();
  } else {
    console.log("Your input was " + input);
  }
}

아마도 모범 사례는 아니지만 나를 위해 일을합니다.


다른 답변은 훌륭하지만 나는 다른 전술을 취할 것이라고 생각했습니다.

정말로 당신이 찾고있는 모든 것이 리눅스에서 특정 파일을 느리게하는 것입니다 :

 rm slowfile; mkfifo slowfile; perl -e 'select STDOUT; $| = 1; while(<>) {print $_; sleep(1) if (($ii++ % 5) == 0); }' myfile > slowfile  &

노드 myprog slowfile

5 줄마다 1 초 동안 잠을 듭니다. 노드 프로그램은 기록기만큼 느리게 진행됩니다. 다른 작업을 수행하는 경우 정상적인 속도로 계속 진행됩니다.

mkfifo는 선입 선출 파이프를 생성합니다. 이것이 작동하는 이유입니다. 펄 라인은 당신이 원하는대로 빨리 쓸 것입니다. $ | = 1은 출력을 버퍼링하지 않는다고 말합니다.


에 대한 자세한 정보

yield sleep(2000); 

Redux-Saga를 확인해야합니다 . 그러나 모델 프레임 워크로 Redux를 선택한 경우에만 적용됩니다 (엄격히 필요하지는 않지만).


이 질문에 대한 답변을 읽은 후 필요한 경우 콜백을 수행 할 수있는 간단한 함수를 모았습니다.

function waitFor(ms, cb) {
  var waitTill = new Date(new Date().getTime() + ms);
  while(waitTill > new Date()){};
  if (cb) {
    cb()
  } else {
   return true
  }
}

참고 : https://stackoverflow.com/questions/14249506/how-can-i-wait-in-node-js-javascript-l-need-to-pause-for-a-period-of-time

반응형