// 最主要的是理解setTimeout和(浏览器执行程序 || resolve执行位置)的顺序就能吃透了

//(MD 楞是看了我2个小时时间 真的是费脑洞︿( ̄︶ ̄)︿)X.then.then

以下:我把完整版摘出来
try {
module.exports = Promise
} catch (e) {} function Promise(executor) {
var self = this self.status = 'pending'
self.onResolvedCallback = []
self.onRejectedCallback = [] function resolve(value) {
if (value instanceof Promise) {
return value.then(resolve, reject)
}
setTimeout(function() { // 异步执行所有的回调函数
if (self.status === 'pending') {
self.status = 'resolved'
self.data = value
for (var i = 0; i < self.onResolvedCallback.length; i++) {
self.onResolvedCallback[i](value)
}
}
})
} function reject(reason) {
setTimeout(function() { // 异步执行所有的回调函数
if (self.status === 'pending') {
self.status = 'rejected'
self.data = reason
for (var i = 0; i < self.onRejectedCallback.length; i++) {
self.onRejectedCallback[i](reason)
}
}
})
} try {
executor(resolve, reject)
} catch (reason) {
reject(reason)
}
} function resolvePromise(promise2, x, resolve, reject) {
var then
var thenCalledOrThrow = false if (promise2 === x) {
return reject(new TypeError('Chaining cycle detected for promise!'))
} if (x instanceof Promise) {
if (x.status === 'pending') { //because x could resolved by a Promise Object
x.then(function(v) {
resolvePromise(promise2, v, resolve, reject)
}, reject)
} else { //but if it is resolved, it will never resolved by a Promise Object but a static value;
x.then(resolve, reject)
}
return
} if ((x !== null) && ((typeof x === 'object') || (typeof x === 'function'))) {
try {
then = x.then //because x.then could be a getter
if (typeof then === 'function') {
then.call(x, function rs(y) {
if (thenCalledOrThrow) return
thenCalledOrThrow = true
return resolvePromise(promise2, y, resolve, reject)
}, function rj(r) {
if (thenCalledOrThrow) return
thenCalledOrThrow = true
return reject(r)
})
} else {
resolve(x)
}
} catch (e) {
if (thenCalledOrThrow) return
thenCalledOrThrow = true
return reject(e)
}
} else {
resolve(x)
}
} Promise.prototype.then = function(onResolved, onRejected) {
var self = this
var promise2
onResolved = typeof onResolved === 'function' ? onResolved : function(v) {
return v
}
onRejected = typeof onRejected === 'function' ? onRejected : function(r) {
throw r
} if (self.status === 'resolved') {
return promise2 = new Promise(function(resolve, reject) {
setTimeout(function() { // 异步执行onResolved
try {
var x = onResolved(self.data)
resolvePromise(promise2, x, resolve, reject)
} catch (reason) {
reject(reason)
}
})
})
} if (self.status === 'rejected') {
return promise2 = new Promise(function(resolve, reject) {
setTimeout(function() { // 异步执行onRejected
try {
var x = onRejected(self.data)
resolvePromise(promise2, x, resolve, reject)
} catch (reason) {
reject(reason)
}
})
})
} if (self.status === 'pending') {
// 这里之所以没有异步执行,是因为这些函数必然会被resolve或reject调用,而resolve或reject函数里的内容已是异步执行,构造函数里的定义
return promise2 = new Promise(function(resolve, reject) {
self.onResolvedCallback.push(function(value) {
try {
var x = onResolved(value)
resolvePromise(promise2, x, resolve, reject)
} catch (r) {
reject(r)
}
}) self.onRejectedCallback.push(function(reason) {
try {
var x = onRejected(reason)
resolvePromise(promise2, x, resolve, reject)
} catch (r) {
reject(r)
}
})
})
}
} Promise.prototype.catch = function(onRejected) {
return this.then(null, onRejected)
} Promise.deferred = Promise.defer = function() {
var dfd = {}
dfd.promise = new Promise(function(resolve, reject) {
dfd.resolve = resolve
dfd.reject = reject
})
return dfd
} var a = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(1)
}, 500)
console.log(13123)
}) a.then((params) => {
console.log(params)
return 2
}).then((dd) => {
console.log(dd)
}) a.then((dd) => {
console.log(dd)
return new Promise(function (resolve) {
setTimeout(() => {
resolve('dengdai')
}, 1000)
})
}).then(c => {
console.log(c)
}) a.then((dd) => {
console.log(dd)
})

Promise(interesting)的更多相关文章

  1. 基础知识:Promise(整理)

    基础知识:Promise(整理) (来自牛客网)下面关于promise的说法中,错误的是(D) A. resolve和reject都是直接生成一个进入相应状态的promise对象,其参数就是进入相应状 ...

  2. 大白话讲解Promise(二)理解Promise规范

    上一篇我们讲解了ES6中Promise的用法,但是知道了用法还远远不够,作为一名专业的前端工程师,还必须通晓原理.所以,为了补全我们关于Promise的知识树,有必要理解Promise/A+规范,理解 ...

  3. 形象的讲解angular中的$q与promise(转)

    以下内容摘自http://www.ngnice.com/posts/126ee9cf6ddb68 promise不是angular首创的,作为一种编程模式,它出现在……1976年,比js还要古老得多. ...

  4. 关于promise(一)

    该新特性属于 ECMAScript 2015(ES6)规范,在使用时请注意浏览器兼容性. 由于ES6原生提供Promise,所以无需安装Promise库.但在ES5环境下我们可以使用bluebird库 ...

  5. 给你一个承诺 - 玩转 AngularJS 的 Promise(转)

    在谈论Promise之前我们要了解一下一些额外的知识:我们知道JavaScript语言的执行环境是“单线程”,所谓单线程,就是一次只能够执行一个任务,如果有多个任务的话就要排队,前面一个任务完成后才可 ...

  6. Promise (1) 如何使用Promise

    Promise 也是面试高频问题, 今天我们来看看Promise是什么, 能做什么, 怎么用, 下一期我们自己来模拟一个myPromise 1  Promise 是什么 我们要学会自己给自己提问, 才 ...

  7. 学JS的心路历程-Promise(三)

    今天我们来说then一些特殊情况以及Promise.all()与Promise.race(). 我们都知道函式作为参数传入时,可以参照的方式传入,也能传入时执行拿回传值作使用: function us ...

  8. 学JS的心路历程-Promise(二)

    昨天有说到Promise的创建以及then的用法,今天我们来看错误处理. then onRejected 我们昨天有提到说,then两个函式参数,onFulfilled和onRejected,而onR ...

  9. 学JS的心路历程-Promise(一)

    今天在进入Promise代码之前,我们先来用个例子来解释Promise是什么. 未来值 假设我们今天来到快餐店,点了一个汉堡,付钱给店员. 点了餐点并付费,可以理解为我们发送了一个请求,希望得到一个回 ...

随机推荐

  1. pytest 11 allure2生成html报告

    allure是一个report框架,支持java的Junit/testng等框架,当然也可以支持python的pytest框架,也可以集成到Jenkins上展示高大上的报告界面. 环境准备 1.pyt ...

  2. Linux下安装部署Samba共享盘的操作手册

    简述 Samba是在Linux和UNIX系统上实现SMB协议的一个免费软件,由服务器及客户端程序构成.SMB(Server Messages Block,信息服务块)是一种在局域网上共享文件和打印机的 ...

  3. Fiddler状态栏

    Fiddler状态栏显示了Fiddler的一些配置信息,我们也可以点击这些配置信息进行快速配置. 以下图为例: 状态栏一共显示了四项信息:1.Capturing/空:2.过滤进程类型:3.Web Se ...

  4. SpringBoot系列: Web应用鉴权思路

    ==============================web 项目鉴权============================== 主要的鉴权方式有:1. 用户名/密码鉴权, 然后通过 Sess ...

  5. [物理学与PDEs]第5章习题3 第二 Piola 应力张量的对称性

    试证明: 在物质描述下, 动量矩守恒定律等价于第二 Piola 应力张量的对称性. 证明: 由 $$\beex \bea \int_{G_t}\rho\sex{{\bf y}\times\cfrac{ ...

  6. jQuery1.9及以上版本检测IE版本号

    jQuery 从 1.9 版开始,移除了 $.browser 和 $.browser.version , 取而代之的是 $.support . 在更新的 2.0 版本中,将不再支持 IE 6/7/8. ...

  7. .net实现md5加密 sha1加密 sha256加密 sha384加密 sha512加密 des加密解密

    写项目时,后台一直用md5加密,一天群里人问,除了MD5还有其它的加密方法吗?当时只知道还有个SHA,但怎么实现什么的都不清楚,于是当网上找了下,把几种常见的加密方法都整理了下,用winform写了个 ...

  8. oracle建表 和 设置主键自增

    1.新建table CREATE TABLE ysb_log( id ) primary key not null , tbdate ) NULL, tb_time ) NOT NULL, tblog ...

  9. main 及Scanner

    通过main方法的args数组可以从控制台获取一组字符串数据. 1.Scanner类用于扫描从控制台输入的数据,可以接收字符串和基本数据类型的数据. 2.Scanner类位于java.util.Sca ...

  10. [笔记]猿计划(WEB安全工程师养成之路系列教程):02HTML头部标签

    1.什么是HTML? HTML是用来描述网页的一种语言 HTML——超文本标记语言(Hyper Text Markup Language) HTML不是编程语言,是一种标记语言 标记语言是一套标记标签 ...