Why is the synchronous sleep function not performed asynchronously, being internally promised?

I am trying to wrap my head around promises and how JavaScript works with it in the queue and in the event loop, etc.

I thought that if I put a slow synchronous function inside a promise, this slow synchronization function would be delegated to the background, and I could use .thento deal with it when it was done.

function syncSleep(ms){
    var end = new Date().getTime() + ms;
    var start = new Date().getTime();

    while (start < end) {
      start = new Date().getTime();
    }
}

function p() {
  return new Promise(function(resolve) {
     syncSleep(5000);
     resolve("syncSleep done!");
  });
}

p().then( function(s) {
  var div = document.getElementById('async');
  div.innerHTML = s;
} );

var div = document.getElementById('sync');
div.innerHTML = "This should appear right away! (but it doesn't)";

https://jsfiddle.net/7mw6m2x5/

The user interface is not responding while this code is running.

So I was wondering, can someone explain what is going on here? Are Promises the only way to handle code that has already been "executed" by async?

(If so, how is this done?)

, , ? - ?

. .

+3
3

, .

Javascript , .

Promises - . . :

http://www.html5rocks.com/en/tutorials/es6/promises/

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise

, WebWorkers:

https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers

:

"- - . , ".

:

script, . , , .

function setVal(s) {
  var divAsync = document.getElementById('async');
  var innerDiv = document.createElement('div');
  innerDiv.innerHTML = s + '<br>';
  divAsync.appendChild(innerDiv);
}


function syncSleep(ms) {
  var end = new Date().getTime() + ms;
  var now = new Date().getTime();
  var stepBegin = new Date().getTime();
  var step = 0;

  // This loop is blocking
  // The UI will only refresh after the loop completion
  while (now < end) {
    now = new Date().getTime();
    step = now - stepBegin;
    if (step >= 1000) {
      setVal(now);
      step = 0;
      stepBegin = now;
    }
  }

}

function pBlock() {
  return new Promise(function(resolve) {
    syncSleep(3200);
    resolve("pBlock syncSleep done!");
  });
}


function noBlockUpdate(ms, resolve) {
  var end = new Date().getTime() + ms;
  var now = new Date().getTime();
  var stepBegin = new Date().getTime();
  var step = 0;

  function noBlock() {
    now = new Date().getTime();

    // paint every 1000ms;
    step = now - stepBegin;
    if (step >= 1000) {
      setVal(now);
      step = 0;
      stepBegin = now;
    }

    if (now < end) {
      // NB: this is going to be called thousands of times
      // But the UI will still update every 1000 ms
      setTimeout(noBlock);
    } else {
      resolve("pNoBlock done!");
    }
  };
  noBlock();
}

function pNoBlock() {
  return new Promise(function(resolve) {
    noBlockUpdate(3200, resolve);
    setVal("pNoBlock launched!");
  });
}



pNoBlock().then(setVal);

var divSync = document.getElementById('sync');
divSync.innerHTML = "This appears right away!";



// Just wait 4 seconds so the non-blocking code completes
setTimeout(function() {
  // Clear all div's
  document.getElementById('sync').innerHTML = '';
  document.getElementById('async').innerHTML = '';

  var divSync = document.getElementById('sync');
  divSync.innerHTML = "This does not appear right away, only after the blocking operation is complete!";

  pBlock().then(setVal);
}, 4000);
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>

<body>

  <div id="sync"></div>

  <div id="async"></div>

</body>

</html>
Hide result
+4

Promises , " ?"

. Promises . , API. resolve() .then().

, Promise, . , .then() , , - .

, , ?

. syncSleep() setTimeout().

function p() {
  return new Promise(function(resolve) {
    setTimeout(function () {
      resolve("syncSleep done!");
    }, 5000);
  });
}

, / - -.

, , setTimeout(). , . , , , .

+3

Promises are not threads. This is just sugar for handling successful events and failures (callbacks) in single-threaded code.

The callback to the constructor new Promise(cb)is immediate and synchronous. Callbacks passed to .then(cb)/ .catch(cb)are executed on the next tick after the promise is resolved / rejected, but they also work on the same thread-only.

+2
source

Source: https://habr.com/ru/post/1683955/


All Articles