万字详解JavaScript手写一个Promise

yizhihongxing

万字详解JavaScript手写一个Promise攻略

什么是Promise

Promise是一个JS的异步编程解决方案,对于那些需要等待其他代码执行完成(网络请求等)才可以执行的代码块提供了更好的控制方法。

Promise对象有三种状态: pending, resolve, reject。pending状态表示等待执行,resolve状态表示完成执行,而reject状态表示执行失败。

手写Promise实现

下面我们来手写一个Promise实现,此Promise有thencatch方法对完成状态与失败状态进行处理。

pseudo code:

var Promise = function (executor) {

  this.status = 'pending';
  this.value = null;
  this.reason = null;
  this.onFulfilledCallbacks = [];
  this.onRejectedCallbacks = [];

  var resolve = function (value) {
    if (this.status === 'pending') {
      this.status = 'fulfilled';
      this.value = value;
      this.onFulfilledCallbacks.forEach(function (callback) {
        callback();
      });
    }
  };

  var reject = function (reason) {
    if (this.status === 'pending') {
      this.status = 'rejected';
      this.reason = reason;
      this.onRejectedCallbacks.forEach(function (callback) {
        callback();
      });
    }
  };

  try {
    executor(resolve.bind(this), reject.bind(this));
  } catch (err) {
    reject.bind(this)(err);
  }
};

Promise.prototype.then = function (onFulfilled, onRejected) {
  if (this.status === 'pending') {
    var self = this;
    var promise = new Promise(function (resolve, reject) {
      self.onFulfilledCallbacks.push(function () {
        try {
          var result = onFulfilled(self.value);
          resolve(result);
        } catch (err) {
          reject(err);
        }
      });

      self.onRejectedCallbacks.push(function () {
        try {
          var reason = onRejected(self.reason);
          resolve(reason);
        } catch (err) {
          reject(err);
        }
      });
    });
  }

  if (this.status === 'fulfilled') {
    var promise = new Promise(function (resolve, reject) {
      try {
        var result = onFulfilled(this.value);
        resolve(result);
      } catch (err) {
        reject(err);
      }
    });
  }

  if (this.status === 'rejected') {
    var promise = new Promise(function (resolve, reject) {
      try {
        var reason = onRejected(this.reason);
        resolve(reason);
      } catch (err) {
        reject(err);
      }
    });
  }

  return promise;

};

Promise.prototype.catch = function (onRejected) {
  return this.then(null, onRejected);
};

其中,我们定义了一个executor函数(这个函数会立马被执行),并需要通过该函数手写实现Promise对象的resolve,reject等方法和属性,以及then和catch方法。

Promise用例

下面来看一个使用手写Promise实现异步编程的例子,其中我们模拟了一个网络请求,若请求成功,则进行下一步处理并调用resolve方法,否则调用reject方法。

var request = new Promise(function(resolve, reject) {
  setTimeout(function() {
    var result = {
      status: 200,
      data: {
        message: 'Request has been successfully processed.'
      }
    };
    resolve(result);
  }, 1000);
});

request.then(function(response) {
  console.log(response.data.message);
  return response;
})
.then(function(response) {
  console.log('Request has been successfully handled.');
})
.catch(function(error) {
  console.log(error);
});

在上面的例子中,我们可以看到我们用request变量来接收手写Promise对象的实例,并在then方法里对成功状态进行处理,并对catch方法进行错误状态的处理。

再来看另外一个类似的例子,这里我们会尝试Promise.all方法,它可以让我们同时执行多个Promise对象,而且只有所有的Promise get resolve状态,才会执行all对应的回调。

var request1 = new Promise(function (resolve, reject) {
  setTimeout(function () {
    resolve('Request 1 is finished.');
  }, 1000);
});

var request2 = new Promise(function (resolve, reject) {
  setTimeout(function () {
    resolve('Request 2 is finished.');
  }, 2000);
});

var request3 = new Promise(function (resolve, reject) {
  setTimeout(function () {
    resolve('Request 3 is finished.');
  }, 3000);
});

Promise.all([request1, request2, request3])
  .then(function (responses) {
    responses.forEach(function (response) {
      console.log(response);
    });
    console.log('All requests are finished.');
  });

结语

以上是手写Promise实现的攻略以及部分应用场景,可能需要不断的添加对promise对象异步编程解决方案的理解和熟悉,来实现优质高效的代码逻辑。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:万字详解JavaScript手写一个Promise - Python技术站

(0)
上一篇 2023年5月28日
下一篇 2023年5月28日

相关文章

  • vue3.0中使用element UI表单遍历校验问题解决

    下面是详细讲解“vue3.0中使用element UI表单遍历校验问题解决”的完整攻略: 问题描述 在Vue3.0中使用Element UI的表单组件,当需要对表单进行校验时,遍历组件子孙元素时会出现一些问题。例如,遍历组件子孙元素时,如果组件还未被挂载,那么组件的校验信息无法正常获取。这会造成一些校验问题,导致表单不能正常提交。本文将提供一个解决方法,以便…

    JavaScript 2023年6月10日
    00
  • 通过jsonp获取json数据实现AJAX跨域请求

    使用JSONP技术实现AJAX跨域请求的步骤如下: 1.在主页面中定义一个回调函数,函数名保证唯一性。这个回调函数会接受JSON数据作为参数,并对其进行处理。 例如: function handleJsonData(data) { console.log(data); }; 2.在主页面中创建一个script标签,标签的src属性指向JSON数据请求的网址链…

    JavaScript 2023年5月27日
    00
  • JSP和Struts解决用户退出问题

    当用户想要退出系统时,我们需要清除用户的登录状态,以保证安全性和私密性。在JSP和Struts中,都提供了比较简便的实现方式。 JSP解决用户退出问题 在JSP中,我们可以通过Session对象来保存用户登录状态。因此,当用户想要退出系统时,我们只需要清除Session对象,就可以实现该功能。 示例代码: <% session.removeAttrib…

    JavaScript 2023年6月11日
    00
  • 小程序animate动画实现直播间点赞

    下面是关于小程序animate动画实现直播间点赞的完整攻略: 1. 准备工作 在开始实现动画之前,需要先将点赞的代码逻辑实现,即点击点赞按钮后,更新点赞数量并发送点赞请求。 2. 使用CSS动画实现点赞效果 使用wx.createAnimation创建一个动画对象,并设置一个或多个CSS属性。 “`js const animation = wx.creat…

    JavaScript 2023年6月11日
    00
  • 详解javascript如何在跨域请求中携带cookie

    跨域请求中携带Cookie需要进行一些特殊的处理,下面我将从几个方面来讲解如何在跨域请求中携带Cookie。 什么是跨域请求? 在Web开发中,浏览器有同源策略,即只能向同域名、同协议、同端口的服务器端口发送请求。如果客户端需要和非同源的服务器进行通信,就会触发跨域请求。 为什么默认情况下跨域请求无法携带Cookie? 在默认情况下,跨域请求是不会携带Coo…

    JavaScript 2023年6月11日
    00
  • Javascript注入技巧

    Javascript注入技巧 Javascript注入是一种将代码注入到Web页面中的攻击技巧,它可以通过一些手段在Web页面中运行恶意代码。攻击者可以利用这种技术窃取用户的敏感信息、篡改页面内容、运行恶意程序等,对网站和用户造成不良影响。下面是一些Javascript注入的技巧和示例说明。 基础技巧 1. 隐藏字段注入 隐藏字段注入是一种简单的注入技巧,攻…

    JavaScript 2023年5月18日
    00
  • JavaScript常用事件介绍

    下面我将为您详细介绍“JavaScript常用事件”方面的攻略。在JavaScript中,我们可以使用各种事件来相应网页的状态改变和用户的互动。通过事件,我们可以触发一些特定的JavaScript函数,实现对用户行为的响应。 事件介绍 事件是用户在操作网页时触发的一些动作,包括鼠标点击、键盘输入、页面滚动、窗口大小调整等。常见的事件类型包括: 鼠标事件:cl…

    JavaScript 2023年5月27日
    00
  • 解决AJAX中跨域访问出现’没有权限’的错误

    跨域访问的概念 跨域访问是指客户端(前端网页)在访问服务器端(后端网页)时,两者的域名不一致,从而产生了跨域问题。 在现代化网站应用中,由于很多服务器和网站的域名不一致,因此经常会出现无法通过Ajax发送或接收数据的问题,错误信息通常为“没有权限”,这是浏览器的默认安全策略所造成的。 解决AJAX中跨域访问出现“没有权限”错误的攻略 常见的跨域访问解决方案包…

    JavaScript 2023年5月19日
    00
合作推广
合作推广
分享本页
返回顶部