0

The knowledge I have known that setTimout is later than Promise So I want to proof that is true.

I set a setTimeout in script element and did request in React.componentDidMount use axios with async await grammar sugar. But result is setTimtout was console before the didMount.I don't know why this is.

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>order?</title>
</head>

<body>
  <div id="app"></div>
  <div>
    <h2>order list</h2>
    <ol id="ol">

    </ol>
  </div>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.min.js"></script>
  <!--        <script src="https://cdn.bootcss.com/react/16.8.6/umd/react.production.min.js"></script>-->
  <!--        <script src="https://cdn.bootcss.com/react-dom/16.8.6/umd/react-dom.production.min.js"></script>-->
  <script src="https://cdn.bootcss.com/react/15.4.2/react.min.js"></script>
  <script src="https://cdn.bootcss.com/react-dom/15.4.2/react-dom.min.js"></script>

  <script>
    window.olElement = document.getElementById('ol');

    function createElement(text) {
      const element = document.createElement('li')
      element.innerText = text;
      return element;
    }

    async function getData() {
      await axios('https://www.apiopen.top/weatherApi?city=%E5%8C%97%E4%BA%AC').then(() => {
        olElement.appendChild(createElement("axios then in script element"))
      });
      olElement.appendChild(createElement("await res in script element"))
    }

    setTimeout(() => {
      olElement.appendChild(createElement("setTimeout in script element"))
    });

    getData();
  </script>

  <script>
    function _instanceof(left, right) {
      if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) {
        return right[Symbol.hasInstance](left);
      } else {
        return left instanceof right;
      }
    }

    function _typeof(obj) {
      if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
        _typeof = function _typeof(obj) {
          return typeof obj;
        };
      } else {
        _typeof = function _typeof(obj) {
          return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
        };
      }
      return _typeof(obj);
    }

    function _classCallCheck(instance, Constructor) {
      if (!_instanceof(instance, Constructor)) {
        throw new TypeError("Cannot call a class as a function");
      }
    }

    function _defineProperties(target, props) {
      for (var i = 0; i < props.length; i++) {
        var descriptor = props[i];
        descriptor.enumerable = descriptor.enumerable || false;
        descriptor.configurable = true;
        if ("value" in descriptor) descriptor.writable = true;
        Object.defineProperty(target, descriptor.key, descriptor);
      }
    }

    function _createClass(Constructor, protoProps, staticProps) {
      if (protoProps) _defineProperties(Constructor.prototype, protoProps);
      if (staticProps) _defineProperties(Constructor, staticProps);
      return Constructor;
    }

    function _possibleConstructorReturn(self, call) {
      if (call && (_typeof(call) === "object" || typeof call === "function")) {
        return call;
      }
      return _assertThisInitialized(self);
    }

    function _assertThisInitialized(self) {
      if (self === void 0) {
        throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
      }
      return self;
    }

    function _getPrototypeOf(o) {
      _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {
        return o.__proto__ || Object.getPrototypeOf(o);
      };
      return _getPrototypeOf(o);
    }

    function _inherits(subClass, superClass) {
      if (typeof superClass !== "function" && superClass !== null) {
        throw new TypeError("Super expression must either be null or a function");
      }
      subClass.prototype = Object.create(superClass && superClass.prototype, {
        constructor: {
          value: subClass,
          writable: true,
          configurable: true
        }
      });
      if (superClass) _setPrototypeOf(subClass, superClass);
    }

    function _setPrototypeOf(o, p) {
      _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {
        o.__proto__ = p;
        return o;
      };
      return _setPrototypeOf(o, p);
    }

    var A =
      /*#__PURE__*/
      function(_React$Component) {
        _inherits(A, _React$Component);

        function A() {
          _classCallCheck(this, A);

          return _possibleConstructorReturn(this, _getPrototypeOf(A).apply(this, arguments));
        }

        _createClass(A, [{
          key: "componentDidMount",
          value: async function componentDidMount() {
            olElement.appendChild(createElement("react componentDidMount"))
            var res = await axios('https://www.apiopen.top/weatherApi?city=%E5%8C%97%E4%BA%AC').then(res => {
              olElement.appendChild(createElement("axios then in react didMount"))
              return res
            });
            olElement.appendChild(createElement("await res in react didMount"))
          }
        }, {
          key: "render",
          value: function render() {
            return React.createElement("div", null, "A");
          }
        }]);

        return A;
      }(React.Component);

    ReactDOM.render(React.createElement(A, null), document.getElementById('app'));
  </script>


</body>

</html>
Faisal Rahman Avash
  • 1,268
  • 9
  • 13
mqliutie
  • 377
  • 2
  • 17

2 Answers2

0

It's a bit confusing to say that setTimeout runs later than promise as they are both asynchronous and will wait as long as they need to until their task completes.

In this case, running setTimeout with no delay immediatly puts the callback on the event queue. The browser will process all code in the current function before it takes setTimeout off the event queue and runs it.

Axios makes a HTTP request to apiopen. The promise will only resolve after the request has completed, which takes some time, let's say around 500ms or so (you can check how long in the network panel of dev tools). Your other code will continue running, including the setTimeout event, until the http request completes.

A promise is essentially a nicer way of writing a callback, but what really takes time is the asynchronous task you are waiting for.

MDN has some great resources on using Promises. If you are interested in understanding why setTimeout without a delay runs later have a look at the Concurrency model and the Event Loop

elvey
  • 508
  • 5
  • 9
0

Your test case is not relevant to what you want to test. By using axios, you actually put a HTTP request inside a Promise, and the Promise's resolve time is now dependent on when the request is done.

For an unbiased test case, use same function inside Promise and setTimeout like this question.

blaz
  • 3,981
  • 22
  • 37