欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 资讯 > JS手写题解析

JS手写题解析

2025/2/11 22:20:21 来源:https://blog.csdn.net/qq_52368602/article/details/139678197  浏览:    关键词:JS手写题解析

手写Promise

class MyPromise {constructor(executor) { // executor执行器this.status = 'pending' // 等待状态this.value = null // 成功或失败的参数this.fulfilledCallbacks = [] // 成功的函数队列this.rejectedCallbacks = [] // 失败的函数队列const that = thisfunction resolve(value) { // 成功的方法if (that.status === 'pending') {that.status = 'resolved'that.value = valuethat.fulfilledCallbacks.forEach(myFn => myFn(that.value)) //执行回调方法}}function reject(value) { //失败的方法if (that.status === 'pending') {that.status = 'rejected'that.value = valuethat.rejectedCallbacks.forEach(myFn => myFn(that.value)) //执行回调方法}}try {executor(resolve, reject)} catch (err) {reject(err)}}then(onFulfilled, onRejected) {if (this.status === 'pending') {// 等待状态,添加回调函数到成功的函数队列this.fulfilledCallbacks.push(() => {onFulfilled(this.value)})// 等待状态,添加回调函数到失败的函数队列this.rejectedCallbacks.push(() => {onRejected(this.value)})}if (this.status === 'resolved') { // 支持同步调用console.log('this', this)onFulfilled(this.value)}if (this.status === 'rejected') { // 支持同步调用onRejected(this.value)}}
}// 测试
function fn() {return new MyPromise((resolve, reject) => {setTimeout(() => {if(Math.random() > 0.6) {resolve(1)} else {reject(2)}}, 1000)})
}
fn().then(res => {console.log('res', res) // res 1},err => {console.log('err', err) // err 2})

解析:

首先是初始化了一个Promise实例,并定义了状态、值、成功回调和失败回调,并使用that来指向调用者。

resolve函数用于执行成功回调

reject函数用于执行失败函数

try尝试执行executor函数,并传入resolve和reject,当发生err的时候捕捉err

再用then方法注册Promise成功和失败的回调函数

这边可以看下运行的顺序来更好的理解代码

首先executor(resolve,reject)会try,然后最开始肯定是pending状态,会将回调函数调到列队中。

随后settimeout启动生成random,开始执行resolve or reject 

这边是调用了resolve,他会更换状态并且执行列队中的函数

res => {
    console.log('res', res) // res 1
  },

手写AJAX

拿下Promise后就可以趁热打铁来了解AJAX了

// url:"url路径"  type:请求方式  data:请求参数类型  dataType:返回的字符串类型
function ajax({url,type,data,dataType}){
return new Promise(function(resolve,reject){//1. 创建异步请求对象var xhr=getXhr();// 备注:无需通过上面的方式,简单的创建异步请求对象的简化代码如下:// var xhr = window.XMLHttpRequest ? new XMLHttprequest() : new ActiveXObject('Microsoft.XMLHttp');//2.绑定监听事件xhr.onreadystatechange=function(){// 当异步请求状态变为4时,并且返回的状态码为200,接收响应成功if(xhr.readyState==4&&xhr.status==200){// 当返回接收的字符串类型为json串时,自动转换json串if(dataType!==undefined&&dataType.toLowerCase()==="json")var res=JSON.parse(xhr.responseText)else// 否则直接获取返回的响应文本中的内容var res=xhr.responseText// 通过Promise,将返回的数据向后传递,相当于获取到请求数据将数据return出来resolve(res);}}// 如果请求方式为get请求,则将请求参数拼接在url后if(type.toLowerCase()==="get"&&data!==undefined){url+="?"+data;}//3.打开连接xhr.open(type,url,true);// 如果请求方式为post请求,则修改请求消息头if(type.toLowerCase()==="post")//增加:设置请求消息头xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");//4.发送请求if(type.toLowerCase()==="post"&&data!==undefined)xhr.send(data);elsexhr.send(null);})

首先定义了一个函数ajax,并有四个传值,这边可以看下实例,来了解参数定义

// 定义一个函数,使用 ajax 发送请求
function fetchData() {// 请求配置对象,包括 url、type、data、dataTypeconst config = {url: 'https://jsonplaceholder.typicode.com/posts/1', // 示例 APItype: 'GET', // 请求方式,GET 或 POSTdata: null, // 请求参数,对于 GET 请求,参数直接拼接在 URL 后面dataType: 'json' // 返回的数据类型,这里指定为 JSON};// 调用 ajax 函数,并返回 Promise 对象return ajax(config).then(response => {console.log('请求成功:', response);// 这里可以对获取到的数据进行进一步处理或返回return response;}).catch(error => {console.error('请求失败:', error);throw error; // 可以选择抛出异常或者进行其他处理});
}

然后rentun了一个Promise

这里面有很多可能不认识的东西,要逐一了解下

比如toLowerCase,他不会改变原字符串,可以将来的字母都转化为小写字母

JSON.parse可以将字符串转化为javascript对象,但key必须是用双引号包裹的

let str = "Hello World";let lowerCaseStr = str.toLowerCase();console.log(lowerCaseStr); // 输出: "hello world"
console.log(str); // 输出: "Hello World",原始字符串未被改变
// JSON 字符串
const jsonStr = '{"name": "John", "age": 30, "city": "New York"}';// 使用 JSON.parse 解析 JSON 字符串
const jsonObj = JSON.parse(jsonStr);console.log(jsonObj); // 输出: { name: 'John', age: 30, city: 'New York' }
console.log(jsonObj.name); // 输出: "John"
console.log(jsonObj.age); // 输出: 30

这样xhr.onreadystatechange里面的内容就很好理解了,就是当请求成功后将相应内容提取出来作为resolve。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com