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에서도 지원합니다.
더 많은 정보:
- Nodejs의 하모니 플래그 : https://nodejs.org/en/docs/es6/
- 다운로드 할 모든 NodeJS 버전 : https://nodejs.org/en/download/releases/
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');
});
위의 코드는 자바 스크립트의 비동기 콜백 지옥 문제 해결의 부작용입니다. 이것이 또한 자바 스크립트를 백엔드에서 유용한 언어로 만드는 이유이기도합니다. 실제로 이것은 현대 자바 스크립트에 도입 된 가장 흥미로운 개선 사항입니다. 작동 방식을 완전히 이해하려면 생성기 작동 방식을 완전히 이해해야합니다. function
a로 다음 키워드는 *
현대 자바 스크립트의 생성 기능이라고합니다. 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
}
}
'development' 카테고리의 다른 글
부동 소수점은 소수점 이하 두 자리 만 표시합니다 (0) | 2020.03.17 |
---|---|
WebForms UnobtrusiveValidationMode에는 'jquery'에 대한 ScriptResourceMapping이 필요합니다. (0) | 2020.03.17 |
NodeJ를 설치할 수 없습니다 : / usr / bin / env : node : 해당 파일 또는 디렉토리가 없습니다 (0) | 2020.03.17 |
2 차원 배열을 어떻게 회전합니까? (0) | 2020.03.17 |
JPA hashCode () / equals () 딜레마 (0) | 2020.03.17 |