자바스크립트 불수면 sleep () 의 자바스크립트 버전은 무엇입니까?

9744 단어 javascript
이전에 브라우저의 DevTools를 만지작거리며 수면과 관련된 코드를 실현하려고 했지만 자바스크립트에 본 컴퓨터의 수면 기능이 없다는 것을 발견하여 실망하셨습니까?아니면 한 사이트에서 제공하는 JS에서 이 점을 실현하려고 합니까?나는 이전에 그곳에 간 적이 있기 때문에, 내가 이 때문에 찾은 변통 방법, 그리고 만약 당신의 코드가 네트워크 요청을 보내는 것과 관련이 있다면, 왜 그것들은 모두 적합하지 않은지 설명해 보겠습니다. (그리고 당신이 어떤 다른 선택을 했는지)

수면 오류


ECMAScript는 수면 함수를 정의하지 않습니다.그래서 다양한 해커들이 효과를 보려고 시도하고 있다.다음 단락에서 보듯이 그것들은 모두 결점이 있다.
자바스크립트에서 자고 있는 공식 창고 넘침 문제에 대해sleep () 의 자바스크립트 버전은 무엇입니까?찬성표 2408장(본문 초안 이후 12장 증가)을 가지고 11년여 동안 280만 건의 조회를 받았다. 이는 수면이 어떤 응용 프로그램에서 얼마나 중요한지 증명하는 동시에 다른 웹 개발자들이 현재 수면 기능을 스스로 실현해야 한다는 좌절감을 증명한다.

sleep()의 JavaScript 버전은 무엇입니까?


2009년 6월 4일
참고: 7
답: 83
2738

아래sleep 함수(taken from here보다 JavaScript에서 설계pausecomp할 수 있는 방법이 있습니까?
function pausecomp(millis)
{
    var date = new Date();
    var curDate = null;
    do { curDate = new Date(); }
    while(curDate-date < millis);
}
이건...
Open Full Question
지금은 수면이 때때로 매우 중요하다.API에서 데이터를 가져오고 다음 포인터 몇 개에 분산되어 있는 경우 몇 가지 요청을 해야 합니다.모든 요청을 한 번에 트리거하거나 오류 sleep 만 발생하면 429 Too many requests 상태 코드에 의해 차단될 수 있습니다.Instagram의 GraphQL 끝점이 바로 이러한 API 예입니다.몇 번, 나는 내 코드를 요청 사이에 서로 다른 수면 함수를 전달하여 실현시켰다. 그 결과 실행할 때 모든 요청이 한 번에 촉발되어 대부분의 요청이 실패했고 429개의 상태 코드가 있음을 발견했다!
바쁘게 기다리는 해결 방안은 브라우저에서 사용하기에 적합하지 않습니다. 브라우저가 실행될 때 스크립트가 브라우저를 느리게 하고 있음을 알리는 플래카드 경고를 표시하고 사용자가 브라우저를 멈추도록 선택하기 때문입니다. (적어도 Firefox는 이렇게 할 수 있고, Chrome도 이렇게 할 수 있습니다.)기다리느라 바쁜javascript 코드를 멈추고 페이지를 파괴할 수도 있습니다.따라서 우리는 다른 선택을 모색해야 한다.
최상위 수준의 솔루션은 다음 코드 세그먼트를 사용합니다.
function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

// It's called using `await sleep(ms)`.

문제


이것은 매우 유효하지만, 비동기 함수가 정상적인 함수에 호출되지 않은 경우에만 사용된다.이것은 await를 사용하기 때문에 비동기 함수에서 호출해야 합니다.함수 수면 시 비비동기 호출 프로그램의 실행을 회복하는 불쾌한 결과가 발생할 수 있다.만약 코드가 직렬로 실행되고 호출자가 호출한 함수가 완성되기 전에 실행을 회복하지 않는다고 가정한다면, async 이 가설을 깨뜨렸다.
자바스크립트에서는 상위 함수에 독립적으로 실행되는 함수async가 있습니다.부함수 사용await 키워드를 강제로 비동기 함수를 기다리기 위해서는 부함수도 async로 표시해야 한다. 이는 연쇄반응을 일으키고 아래에서 위까지의 모든 함수는 async 함수가 된다.비록 이렇게 코드를 작성하는 것은 틀리지 않지만, 모든 await 키워드는promise를 되돌려줍니다. 비동기 함수가 다른 형식을 되돌려주더라도 (promise resolve() 에서 매개 변수로 포장됩니다.)그래서 현재 당신은 남은 함수체를 then() 호출 주위에 두어야 합니다. 물건을 되돌릴 때마다 다른 라인에 포장되어 있기 때문에 then 호출 후에 되돌려 주는 값을 이용하려면 다시 .then() 호출해야 합니다. 만약 그것이 함수 중의 마지막 then() 이라면 약속된 되돌려 주는 값은 async 호출자에게 전파됩니다.
이렇게 생각할 수 있다.
async function someFunc() { /* ... */ }

async function callee() {
  p = await someFunc()
  // `p` is a Promise
  p.then(ret => {
    // `ret` is whatever `someFunc` was supposed to return
  })
}
보시다시피 이 문제는 좋은 해결 방안이 없습니다.스택에 문제가 넘치는 다른 답안은 매우 복잡하다.

차례로 돌아가다, 순환하지 않는다?


순환 안에서만 자고 문제가 넘치는 맨 윗부분 해결 방안을 사용하면 실행할 때 불쾌한 놀라움을 줄 수 있습니다. 모든 sleep 순환 계수기의 모든 값을 동시에 실행합니다. (while 문구를 사용하면 무한대합니다.) 그리고 가능한 한 많은 순환체를 동시에 촉발합니다.이것은 결국 브라우저를 붕괴시켰다.
귀속은 해결 방법입니다. 같은 매개 변수를 사용하여 내부에서 비동기 함수를 호출하고 즉시 같은 문장에서 값을 되돌릴 수 있습니다.이것은 또한 중계에서 계속 귀속되거나 준순환하는 조건을 실현할 수 있습니다.이것이 바로 그것의 작업 원리다.
async function sleep(ms) { /* exact same `sleep` function as above */ }

async function foo(bar) {
  someAsyncFunc().then(retSomeAsyncFunc => {
    if (/* some condition involving `retSomeAsyncFunc` matches */) {
      // This returns a promise with the return value inside
      // to whoever called `foo()` initially
      return foo(bar)
    }
    // Additional processing...
    return someValue // Optional, can return nothing at all
  })
}
이러한 상황에서 귀속을 사용하는 가장 큰 문제는 귀속 (순환) 이 너무 많으면 호출 창고 크기의 제한에 도달할 수 있다는 것이다.브라우저마다 호출 창고 제한이 다르기 때문에 귀속할 때 조심해야 한다.
일단 끼워 넣는 순환이 필요하다면, 이런 방법도 매우 혼란스러워질 것이다.만약 정의된 함수만 귀속할 수 있다면, 우리는 어떻게 외부 순환을 하나의 귀속으로 바꾸고 내부 순환의 귀속을 호출하여 내부 순환 자체가 임의의 조작을 할 수 있습니까?
이전 단락을 이해하지 못하더라도 두 순환이 하나의 귀속 함수를 공유하지 못하는 것을 쉽게 볼 수 있습니다.질문 보셨어요?

글로벌 변수를 사용하여 간격을 설정합니까?


또 다른 해결 방법은 리셋 함수setInterval()와 자고 싶은 시간, 그리고 당신의 순환체를 사용하는 것이다.이런 방법은 두 가지 단점이 있다.
  • 리셋은 파라미터를 받아들일 수 없기 때문에 함수 파라미터는 전역 변수에 넣어야 합니다. 전역 변수는 프로그램에 적합하거나 부적합할 수 있습니다.
  • 더 많은 플러그인 순환을 추가할 때, 이 방법은 곧 분해될 것입니다.
  • 원자학기다리다


    나는 그것을 정상적으로 일하게 할 수 있어서 매우 운이 좋다.그것도 비동기 함수 밖에서 일한다.NodeJS에는 적용되지만 Firefox 및 Chrome에는 적용되지 않습니다.*나머지 브라우저는 실행되지 않았습니다Atomics.wait.따라서 이 솔루션은 웹 페이지에서 가져온 Devtools 스크립트나 클라이언트 JS에는 적용되지 않습니다.
    function sleep(n) {
      Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, n);
    }
    
    * 이것은 주 스레드에서 실행되기 때문입니다.특수한 상황을 완전하게 해석하면 원자라고 할 수 있다.특정한 작업 라인에서 기다립니다. 예를 들어 WebGL 렌더링에서 기다립니다. 그러나 이것은 주제에서 벗어났기 때문에 저는 여기서 소개하지 않습니다.

    NodeJS 사용?


    제3자 npm모듈sleep은 진정한 수면 기능을 제공합니다. 코드 경로를 둘로 나누지 않습니다. (호출할 때마다 각각 3과 4입니다. 이것은 많은 네트워크 요청을 의미할 수 있습니다.)그것은 시간 초과가 끝날 때까지 기다렸다가 다음 문장을 실행합니다.약속을 수정하거나 비동기적/대기적으로 작업할 필요가 없습니다.
    내가 보기에 이것은 수면의 궁극적인 기능이다.이것은 이 기능을 지원하는 언어 C++로 작성되었습니다.불행하게도 브라우저 내부에는 이런 등가물이 없다.NodeJS 솔루션입니다.
    이 모듈을 사용하는 단점 중 하나는 전체 이벤트 순환이 수면할 때 멈추는 것이다.이것은 아마도 네가 원하는 것일 것이다. 그러나 만약 네가 두 세계에서 조금이라도 찾고 싶다면, 즉, 한 라인에서 자고 싶다면, 그것은 여기에 없다.
    또한 이 모듈은 C++로 작성되었기 때문에 이를 컴파일해야 설치할 수 있습니다.노드 옆에 Visual Studio 구축 도구와 도구 패키지를 설치하지 않으면 설치할 공간이 충분하지 않을 수 있습니다.

    Javascript는 Java가 아닙니다.


    Javascript의 실행 프로세스는 기존 언어와 완전히 다릅니다.코드를 작성해서 비동기적, 비동기적, 약속적, 또는 다른 순환을 충분히 사용해야 합니다.본문이 방금 시범한 중간 노선이 없다.약속된 내장 함수의 수량을 되돌려 주기 때문에 순환을 사용하여 막기 작업을 하는 것이 점점 불가능해진다.
    네트워크 요청을 보내려면 Javascript 프로그램을 전통적인 방식으로 작성하지 마십시오.이 모든 함수는 비동기적입니다. 이 함수는 모든 부모 함수도 비동기적으로 만들고 then 함수체를 연결합니다.다른 sleep로 실행할 수 있지만, 전제 조건은 순환할 필요가 없다는 것입니다.가능하다면, 순환 문장을 사용하지 않도록 순환을 전개합니다.

    우리 끝났어.


    만약 당신이 이 문제를 처리하는 데 관한 문장의 정정과 더 좋은 건의, 그리고 이 문제에 대한 피드백이 있다면, 나는 받아들이고 싶습니다.
    이미지 시작Pexels부터Pixabay

    좋은 웹페이지 즐겨찾기