sourcecode

Node.js(JavaScript)에서 대기하려면 어떻게 해야 합니까?나는 일정 기간 동안 일시 정지할 필요가 있다.

copyscript 2022. 9. 11. 17:28
반응형

Node.js(JavaScript)에서 대기하려면 어떻게 해야 합니까?나는 일정 기간 동안 일시 정지할 필요가 있다.

개인 요구에 맞는 콘솔 스크립트를 개발하고 있습니다.장기간 일시정지할 수 있어야 하는데, 제가 조사한 바로는 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');
    // end of code

저도 이런 걸 봤어요

    yield sleep(2000);

그러나 Node.js는 이를 인식하지 못합니다.

어떻게 하면 이 긴 휴지를 실현할 수 있을까요?

2021년 1월 갱신: 노드 리플리케이션에서는--experimental-repl-await

$ node --experimental-repl-await
> const delay = ms => new Promise(resolve => setTimeout(resolve, ms))
> await delay(1000) /// waiting 1 second.

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

async function init() {
  console.log(1);
  await sleep(1000);
  console.log(2);
}

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

「 」를 사용하는 async/await "node-v8" 을 node-v8 을 사용해야 --harmony

업데이트 2019년 6월 : 최신 버전의 노드 사용JS는 개봉 후 바로 사용할 수 있습니다.명령줄 인수를 지정할 필요가 없습니다.오늘날에는 구글 크롬도 그것을 지원한다.

2020년 5월 업데이트: 머지않아await★★★★★★★★★★★★★★★★★★★★★★★★★★★★★

await sleep(1000)
function sleep(ms) {
  return new Promise((resolve) => {
    setTimeout(resolve, ms);
  });
}

제안은 3단계에 있다.Web Pack 5(alpha)를 사용하면 지금 바로 사용할 수 있습니다.

상세 정보:

  • Nodejs의 하모니 플래그: https://nodejs.org/en/docs/es6/
  • 모든 노드다운로드용 JS 버전: https://nodejs.org/en/download/releases/

의존 관계가 없는 최단 솔루션:

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

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

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);

쟈니랑 비슷해HK의 솔루션이지만 훨씬 깔끔하고 쉽게 확장할 수 있습니다.

이것은 간단한 블로킹 기술입니다.

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

스크립트에서 다른 일(콜백 등)이 발생하지 않는 한 차단됩니다.하지만 이것은 콘솔스크립트이기 때문에 필요한 것이기도 합니다.

후에 를 '지연 후 실행할 코드'에 넣습니다.setTimeout★★★★

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

노드 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
});

오래된 노드 버전(원래 답변)

Windows와 Linux에서 동작하는 비동기 sleeve를 원했습니다.장시간의 루프에 CPU를 의존하지 않고 말이죠.sleep 패키지를 사용해 봤지만, Windows 박스에 인스톨 되지 않습니다.사용 결과:

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

설치하려면 다음과 같이 입력합니다.

npm install system-sleep

당신의 코드로,

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

마법처럼 작동한다.

현대 Javascript를 사용한 심플하고 우아한 수면 기능

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

의존관계도 콜백헬도 없습니다.그게 끝입니다:-)


질문의 예를 고려하면 2개의 콘솔로그 사이에서 sleeve 하는 방법은 다음과 같습니다.

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

main();

은 이제 이 '드로백'이어야 한다는 입니다.async하지만 이미 아마 자바스크립트를 사용하고이다(적어도이다).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

"코드 골프"를 원하는 경우 다른 답변의 일부를 여기서 간략하게 작성할 수 있습니다.

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

제 의 '노드를 입니다.util과 그 도서관promisify는, 것(의 것을 약속 베이스 것되어 있습니다.

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

, 「 정지」를하면, 간단하게 일시정지할 수 있습니다.await를 걸다sleep★★★★

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

편집: 코멘트에 기재되어 있듯이, 그것을 1행으로 줄일 수도 있습니다.

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

굳이 굳이 만들고 싶지 않다면.sleep★★★★

await require('util').promisify(setTimeout)(1000);

이 질문은 상당히 오래되었지만 최근 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/nodej에서는 다음과 같이 동작합니다.

const sneSync = require "child_process").동기 생성;

var sleep = spanSync('sleep', [1.5]);

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

지정하는 시간은 초단위로 지정할 수 있지만 분수로 지정할 수 있습니다.다른 OS에도 같은 명령어가 있는지 모르겠습니다.

노드에서는 Promise를 사용해 보세요.JS

라이너 1대

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

로 사용하다NodeJS

const sleep = async (milliseconds) => {
    await new Promise(resolve => setTimeout(resolve, milliseconds));
}

같은 기능을 사용하다

await sleep(5000)

저는 최근에 대기라고 불리는 단순한 추상화를 만들었습니다.sync 모드로 비동기 함수를 호출합니다(노드 맵에 근거합니다).ES6 제너레이터를 기반으로 한 버전도 있습니다.

https://github.com/luciotato/waitfor

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

필요할 때 순차적으로 코드화할 수 있습니다. 즉, 개인적인 용도로 스크립트를 단순화하는 데 매우 적합합니다.

wait를 사용합니다.코드는 다음과 같습니다.

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. 

또, 동기 모드로 비동기 함수를 호출할 수도 있습니다.예를 확인해 주세요.

Node.js 15 이상부터 Timers Promise API를 사용할 수 있습니다.문란하게 할 필요는 없어setTimeout서드파티 라이브러리에 의존할 수도 있습니다.

import { setTimeout } from 'timers/promises';

await setTimeout(1000);

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(...).

또, 이것은 비동기 sleep입니다.이벤트 루프는 차단되지 않습니다.블로킹 sleep이 필요한 경우 C++ 바인딩을 사용하여 블로킹sleep을 실현하는 이 라이브러리를 사용합니다(단, 비동기 환경과 같은 노드에서는 블로킹sleep이 필요한 경우는 거의 없습니다).

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

javascript에서 "기다리기" 위해서는 상위 답변과 같이 약속을 사용하는 것이 좋습니다.

그럼 어떻게 사용할 수 있을까요?

다음은 5초 서브프로세스가 4초 메인프로세스의 파라미터를 비블로킹 방식으로 큐잉하는 간단한 예입니다.

const wait = (seconds) => 
    new Promise(resolve => 
        setTimeout(() => 
            resolve(true), seconds * 1000))

const process = async (items, prepTask, mainTask) => {
    const queue = [];
    let done = false;

    items.forEach((item, i) => {
        prepTask(item).then(() => {
            queue.push(item);
            if (i == items.length -1) {
                done = true;
            }
        })
    })

    while (!done || queue.length) {
        if (queue.length) {
            const workload = queue.shift();
            await mainTask(workload)
        } else {
            console.log('waiting for subtask to queue')
            await wait(1);
        }
    }
}

// Usage Example

const ids = [1,2,3,4,5,6,7,8,9,10];

const prepTask = async (id) => {
    await wait(id * 5)
    return id * 5;
}

const mainTask = async (workload) => {
    console.log('excuting workload: ', workload);
    const result = await wait(4);
    return { workload, result }
}

process(ids, prepTask, mainTask)
    .then(() => console.log('done'))
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');
});

위의 코드는 Javascript의 비동기 콜백 지옥 문제 해결의 부작용입니다.이것이 바로 Javascript가 백엔드에서 유용한 언어라고 생각하는 이유이기도 합니다.사실 이것이 현대의 Javascript에서 소개된 가장 흥미로운 개선점이라고 생각합니다.제너레이터의 작동 방식을 완전히 이해하려면 제너레이터의 작동 방식을 완전히 이해해야 합니다.function키워드 뒤에 a가 이어집니다.*현대의 Javascript에서는 제너레이터 함수라고 불립니다.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;

simple 우리는 어떤 이벤트가 발생할 때까지 5초 동안 기다립니다(이것은 코드의 다른 어딘가에서 true로 설정된 done 변수에 의해 나타납니다). 또는 타임아웃이 만료되면 100ms마다 체크합니다.

    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;
        }
    })();

일부 사용자에게는 받아들여진 답변이 기능하지 않습니다.다른 답변을 찾았는데, 이 답변은 저에게 효과가 있습니다.set Timeout() 콜백에 파라미터를 전달하려면 어떻게 해야 합니까?

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

'hello'는 전달되는 파라미터입니다.타임아웃 후 모든 파라미터를 전달할 수 있습니다.답변을 주신 @Fabio Phms님 감사합니다.

function doThen(conditional,then,timer) {
    var timer = timer || 1;
    var interval = setInterval(function(){
        if(conditional()) {
            clearInterval(interval);
            then();
        }
    }, timer);
}

사용 예:

var counter = 1;
doThen(
    function() {
        counter++;
        return counter == 1000;
    },
    function() {
        console.log("Counter hit 1000"); // 1000 repeats later
    }
)

현재 스레드 실행을 테스트하기 위해 일시 중단해야 하는 경우 다음을 수행하십시오.

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

다른 대답들도 좋지만 다른 방법을 써야겠다고 생각했어요.

실제로 필요한 것은 Linux에서 특정 파일의 속도를 줄이는 것뿐인 경우:

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

노드 myprog 슬로 파일

이것은 5줄마다 1초씩 슬립합니다.노드 프로그램은 라이터만큼 느려집니다.다른 작업을 하는 경우 정상 속도로 계속됩니다.

mkfifo는 선입선출 파이프를 만듭니다.그게 이 일을 가능하게 하는 거야perl 행은 원하는 만큼 빠르게 쓸 수 있습니다.$|=1은 출력을 버퍼링하지 마십시오.

이 질문의 답변을 읽은 후 필요한 경우 콜백을 수행할 수 있는 간단한 함수를 정리했습니다.

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

에 대한 자세한 내용을 참조해 주세요.

yield sleep(2000); 

레독스-사가를 확인해 보세요다만, 모델 프레임워크로서 Redx 를 선택하는 것에 한정됩니다(단, 엄밀하게는 필요 없습니다).

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

반응형