JS底层挖掘
//Promise版本的Ajax
const getJSON = function(url) {
const promise =new Promise(function(resolve, reject) {
const handler = function() {
if(this.readyState!==4) {
return;
}
if(this.status===200)
{
resolve(this.responseText);
} else {
reject(new Error(this.statusText));
}
};
const client = new XMLHttpRequest();
client.open("GET", url);
client.onreadystatechange=handler;
client.responseType="json";
client.setRequestHeader("Accept", "application/json");
client.send();
});
return promise;
};
getJSON("./demo.json").then(function(json) {
console.log("Contents: "+ json);
}).catch(function(err){
console.log('出错了',err);
});
//Promise实现
(function(window,undefined){ // resolve 和 reject 最终都会调用该函数
var final = function(status,value){
var promise = this, fn, st; if(promise._status !== 'PENDING') return; // 所以的执行都是异步调用,保证then是先执行的
setTimeout(function(){
promise._status = status;
st = promise._status === 'FULFILLED'
queue = promise[st ? '_resolves' : '_rejects']; while(fn = queue.shift()) {
value = fn.call(promise, value) || value;
} promise[st ? '_value' : '_reason'] = value;
promise['_resolves'] = promise['_rejects'] = undefined;
});
} //参数是一个函数,内部提供两个函数作为该函数的参数,分别是resolve 和 reject
var Promise = function(resolver){
if (!(typeof resolver === 'function' ))
throw new TypeError('You must pass a resolver function as the first argument to the promise constructor');
//如果不是promise实例,就new一个
if(!(this instanceof Promise)) return new Promise(resolver); var promise = this;
promise._value;
promise._reason;
promise._status = 'PENDING';
//存储状态
promise._resolves = [];
promise._rejects = []; //
var resolve = function(value) {
//由于apply参数是arguments
final.apply(promise,['FULFILLED'].concat([value]));
} var reject = function(reason){
final.apply(promise,['REJECTED'].concat([reason]));
} resolver(resolve,reject);
} Promise.prototype.then = function(onFulfilled,onRejected){
var promise = this;
// 每次返回一个promise,保证是可thenable的
return new Promise(function(resolve,reject){ function handle(value) {
// 這一步很关键,只有這樣才可以將值傳遞給下一個resolve
var ret = typeof onFulfilled === 'function' && onFulfilled(value) || value; //判断是不是promise 对象
if (ret && typeof ret ['then'] == 'function') {
ret.then(function(value) {
resolve(value);
}, function(reason) {
reject(reason);
});
} else {
resolve(ret);
}
} function errback(reason){
reason = typeof onRejected === 'function' && onRejected(reason) || reason;
reject(reason);
} if(promise._status === 'PENDING'){
promise._resolves.push(handle);
promise._rejects.push(errback);
}else if(promise._status === 'FULFILLED'){ // 状态改变后的then操作,立刻执行
callback(promise._value);
}else if(promise._status === 'REJECTED'){
errback(promise._reason);
}
});
} Promise.prototype.catch = function(onRejected){
return this.then(undefined, onRejected)
} Promise.prototype.delay = function(ms,value){
return this.then(function(ori){
return Promise.delay(ms,value || ori);
})
} Promise.delay = function(ms,value){
return new Promise(function(resolve,reject){
setTimeout(function(){
resolve(value);
console.log('1');
},ms);
})
} Promise.resolve = function(arg){
return new Promise(function(resolve,reject){
resolve(arg);
})
} Promise.reject = function(arg){
return Promise(function(resolve,reject){
reject(arg);
})
} Promise.all = function(promises){
if (!Array.isArray(promises)) {
throw new TypeError('You must pass an array to all.');
}
return Promise(function(resolve,reject){
var i = 0,
result = [],
len = promises.length,
count = len //这里与race中的函数相比,多了一层嵌套,要传入index
function resolver(index) {
return function(value) {
resolveAll(index, value);
};
} function rejecter(reason){
reject(reason);
} function resolveAll(index,value){
result[index] = value;
if( --count == 0){
resolve(result)
}
} for (; i < len; i++) {
promises[i].then(resolver(i),rejecter);
}
});
} Promise.race = function(promises){
if (!Array.isArray(promises)) {
throw new TypeError('You must pass an array to race.');
}
return Promise(function(resolve,reject){
var i = 0,
len = promises.length; function resolver(value) {
resolve(value);
} function rejecter(reason){
reject(reason);
} for (; i < len; i++) {
promises[i].then(resolver,rejecter);
}
});
} window.Promise = Promise; })(window);
JS底层挖掘的更多相关文章
- JS底层知识理解之执行上下文篇
JS底层知识理解之执行上下文篇 一.什么是执行上下文(Execution Context) 执行上下文可以理解为当前代码的执行环境,它会形成一个作用域. 二.JavaScript引擎会以什么方式去处理 ...
- 这是我见过最厉害的--智能代码生成器、html+js+底层+sql全都有、瓦特平台
1:直接上图.图片有点多.我就没全部上传了. (demo.使用方法.数据库bak)下载:http://pan.baidu.com/s/1ntE5bDn 起源: 之前有好多人问我代码生成器的源码.我发了 ...
- JS ----- 底层原理
什么是JS JavaScript是一种基于对象的动态.弱类型脚本语言(简称JS),是一种解释型语言,和其他的编程语言不同,如java/C++等编译型语言,这些语言在代码执行前会进行通篇编译,先编译成字 ...
- Array方面Js底层代码学习记录
一..clear() →Array function clear() { this.length = 0; return this; } 返回清除item的空数组. 例子: var fruits = ...
- JS面向对象(2) -- this的使用,对象之间的赋值,for...in语句,delete使用,成员方法,json对象的使用,prototype的使用,原型继承与原型链
相关链接: JS面向对象(1) -- 简介,入门,系统常用类,自定义类,constructor,typeof,instanceof,对象在内存中的表现形式 JS面向对象(2) -- this的使用,对 ...
- 【译】深入理解python3.4中Asyncio库与Node.js的异步IO机制
转载自http://xidui.github.io/2015/10/29/%E6%B7%B1%E5%85%A5%E7%90%86%E8%A7%A3python3-4-Asyncio%E5%BA%93% ...
- 8款JS框架比较
Dojo Dojo 是目前最为强大的JS框架,它在自己的 Wiki 上给自己下了一个定义,Dojo 是一个用 JavaScript 编写的开源的DHTML工具箱.Dojo 很想做一个“大一统” ...
- js 框架都有哪几种(转载)
目前来看,js框架以及一些开发包和库类有如下几个,Dojo .Scriptaculous .Prototype .yui-ext .Jquery .Mochikit.mootools .moo.fxD ...
- js高级程序设计(第三版)学习笔记(第一版)
ecma:欧洲计算机制造商协会iso/iec:国际标准化和国际电工委员会 dom级别(10*)文档对象模型1:DOM核心(映射基于xml文档)与dom html(在dom核心基础上)2:对鼠标,事件, ...
随机推荐
- php锁定文本框内容的方法
有时候我们希望表单中的文本框是只读的,让用户不能修改其中的信息,如<input type="text" name="zg" value="中国& ...
- java.lang.IllegalArgumentException: Page directive: invalid value for import 问题处理
1.问题说明: 项目原来用的tomcat版本是apache-tomcat-6.0,后来为了安全原因将版本升至apache-tomcat-7.0,发现有的jsp页面出现下面的异常: java.lang. ...
- 记一次失败的Linux安装
这次把整个电脑都装了Ubuntu,向Linux这条路越走越远了,也感谢社会对Linux的支持越来越完善了,才让我下定这个决心,再次表示感谢 之前都是装双系统或者在vm下安装的Linux,现在再装一次, ...
- 数据库存储的数据(如果是<p>数据</p>或者<img src="" />等格式)(asp.net)
1.用方法@Html.Raw() @Html.Raw(数据库提取的数据放在这里)
- C# Label背景透明
Label背景透明是相对于Label的Parent而言的,如果Label的Parent是一个winform,而这个winform又有一个PictureBox,现在Label放在PictureBox上, ...
- Hibernate课程 初探多对多映射2-1 创建数据库表
--创建表 -- 创建项目表 create table project( proid int(10) not null comment '项目Id', proname varchar(30) co ...
- ngnix 反向代理
1 课程目标 掌握nginx+tomcat反向代理的使用方法. 掌握nginx作为负载均衡器的使用方法. 掌握nginx实现web缓存方法. 2 nginx介绍 2.1 ...
- jQuery属性选择器中加变量
$(function () { $('#bkhandle').on('click','#bkdel',function () { $.ajax( { url:"{% url 'bkdel' ...
- python处理字符串:将字符串中的数字相加求和
计算字符串中所有数字的和,字符串中有数字和字母组合而成如果出现连续数字,按照一个数操作具体解释在代码行里: def sum_str(str1): len1=len(str1) #首先将字符串str1的 ...
- vue 钩子函数
beforeRouteEnter 方法名称: beforeRouteEnter 调用时机: 切换路由之前,调用该方法时,页面还没有切换 next调用时机: activated 之后 注意事项: thi ...