Quantcast
Viewing latest article 10
Browse Latest Browse All 44

Answer by Amir Fo for How do I return the response from an asynchronous call?

Using Promise

The most perfect answer to this question is using Promise.

function ajax(method, url, params) {  return new Promise(function(resolve, reject) {    var xhr = new XMLHttpRequest();    xhr.onload = function() {      resolve(this.responseText);    };    xhr.onerror = reject;    xhr.open(method, url);    xhr.send(params);  });}

Usage

ajax("GET", "/test", "acrive=1").then(function(result) {    // Code depending on result}).catch(function() {    // An error occurred});

But wait...!

There is a problem with using promises!

Why should we use our own custom Promise?

I was using this solution for a while until I figured out there is an error in old browsers:

Uncaught ReferenceError: Promise is not defined

So I decided to implement my own Promise class for ES3 to below JavaScript compilers if it's not defined. Just add this code before your main code and then safely use Promise!

if(typeof Promise === "undefined"){    function _typeof(obj) { "@babel/helpers - typeof"; return     _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }    function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }    function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }    function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }    function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }    function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }    function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }    function _classCallCheck(instance, Constructor) { if (!(instance instanceof 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, _toPropertyKey(descriptor.key), descriptor); } }    function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }    function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); }    function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }    var Promise = /*#__PURE__*/function () {"use strict";  function Promise(main) {    _classCallCheck(this, Promise);    this.main = main;    this.mainExecuted = false;    this.resolved = false;    this.rejected = false;    this.promiseChain = [];    this.handleError = function () {};    this.onResolve = this.onResolve.bind(this);    this.onReject = this.onReject.bind(this);  }  _createClass(Promise, [{    key: "then",    value: function then(handleSuccess) {      if (this.resolved) {        if (!this.rejected) {          this.args = handleSuccess(this.args);        }      } else {        this.promiseChain.push(handleSuccess);        this.main(this.onResolve, this.onReject);        this.thenExecuted = true;      }      return this;    }  }, {    key: "catch",    value: function _catch(handleError) {      this.handleError = handleError;      if (!this.mainExecuted) {        this.main(this.onResolve, this.onReject);        this.thenExecuted = true;      }      return this;    }  }, {    key: "onResolve",    value: function onResolve() {      var _this = this;      this.resolved = true;      for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {        args[_key] = arguments[_key];      }      this.args = args;      try {        this.promiseChain.forEach(function (nextFunction) {          _this.args = nextFunction.apply(void 0, _toConsumableArray(_this.args));        });      } catch (error) {        this.promiseChain = [];        this.onReject(error);      }    }  }, {    key: "onReject",    value: function onReject(error) {      this.rejected = true;      this.handleError(error);    }  }]);  return Promise;}();}

Viewing latest article 10
Browse Latest Browse All 44

Trending Articles