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:对鼠标,事件, ...
随机推荐
- EditPlus编写PHP使用技巧
1,建立php模板 方法:在EditPlus的文件目录下,新建template.php文件,写入<?php ?>内容保存,再在editplus的模板中 载入应用即可. 2,建立函数自动补齐 ...
- PHP post & get请求
<?php /** * HTTP 请求类 */ class HttpHelper { const METHOD_GET = 'GET'; const METHOD_POST = 'POST'; ...
- LinuxOS
Linux 操作系统必须完成的两个主要目的 与硬件部分交互, 为包含在硬件平台上的所有底层可编程部件提供服务 为运行在计算机系统上的应用程序(即所谓的用户空间)提供执行环境 一些操作系统运行所有的用户 ...
- PS基础,数学,语文
PS基础(修图) 污点修复画笔工具---设置画笔大小---设置类型(内容识别)---修改图片---完成. 修复画笔工具---设置画笔大小---设置源(取样)---修改图片---完成. 修补工具---设 ...
- Model对象嵌套list赋值方式(备忘)
首先定义Model对象:var deliveryInfoModel = new DeliveryInfo(); 第二步定义嵌套的list对象:var list = new List<Delive ...
- Redis整理第二波(启动、命令)
启动 配置数据库数量: Redis默认开启16个数据库,不能像mysql自定义数据库名称,只能是数值,不能修改. 配置内存大小: 会生成一个和内存大小一样的文件. maxmemory 200mb #在 ...
- vueHistory 模式下,布置到服务器上路由刷新会报nginx404错误
之前写完vue项目后,布置到服务器,用nginx反向代理后,一开始进去,进各种路由都是没问题的,但是一旦f5刷新后就会出现一个nginx404的错误. 经过翻阅vue文档后,发现这是vueHistor ...
- svg用作背景图
svg用做背景图的几种方式 1. 直接使用 background: url('data:image/svg+xml;charset=utf-8,<svg width="10" ...
- 从零开始的全栈工程师——js篇(正则表达式)
正则 就是一条规则 用来检验字符串的格式 目标就是字符串 只要是通过表单提交的数据 都是字符串1.正则定义var reg = new RegExp( )var reg = /格式/ <--简写 ...
- extjs 6
因为最近公司要写一个项目前台所以开始学习extjs前端框架,希望一起共勉. 那么我们的教程就从 Hello World 讲起. helloWorld.js Ext.onReady(function ...