Promises/A+规范 英文
Promises/A+规范 中文
Promise使用
// 同一个promise可以then多次
let p = new Promise(function (resolve, reject) {
resolve('xx')
})
p.then(function (data) {
console.log('success', data)
}, function (err) {
console.log(err);
});
Promise源码解析
Promise源码(一)
- Promise状态: pending, fulfilled 或 rejected.
- then 方法
case.js
let Promise = require('./promise');
let p = new Promise(function (resolve, reject) {
resolve('xxx');
})
// 同一个Promise可以then多次
p.then(function (data) {
console.log(`success ${data}`);
}, function (err) {
console.log(`err ${err}`);
})
promise.js
function Promise(executor) {
let self = this;
// 保存Promise状态,默认pending;三个状态: pending, fulfilled 或 rejected.
self.status = 'pending';
// 保存成功的值
self.value = undefined;
// 保存失败的原因
self.reason = undefined;
// 只有Promise状态为pending才能进行转化
function resolve(value) {
if (self.status === 'pending') {
self.value = value;
self.status = 'fulfilled';
}
}
function reject(reason) {
if (self.status === 'pending') {
self.reason = reason;
self.status = 'rejected';
}
}
try {
executor(resolve, reject); // 跑出异常时,走下一个then的失败
} catch (e) {
reject(e); // 出错,reason就是原因
}
}
Promise.prototype.then = function (onFulFilled, onRejected) {
let self = this;
if (self.status === 'fulfilled') {
onFulFilled(self.value);
}
if (self.status === 'rejected') {
onRejected(self.reason);
}
}
module.exports = Promise;
Promise源码(二)
case.js
let Promise = require('./promise');
let p = new Promise(function (resolve, reject) {
setTimeout(() => {
resolve('延迟1秒');
}, 1000)
})
// 同一个Promise可以then多次
p.then(function (data) {
console.log(`success ${data}`);
}, function (err) {
console.log(`err ${err}`);
})
promise.js
function Promise(executor) {
let self = this;
// 保存Promise状态,默认pending;三个状态: pending, fulfilled 或 rejected.
self.status = 'pending';
// 保存成功的值
self.value = undefined;
// 保存失败的原因
self.reason = undefined;
// 异步方法存起来
self.onResolvedCallbacks = [];
self.onRejectedCallbacks = [];
// 只有Promise状态为pending才能进行转化
function resolve(value) {
if (self.status === 'pending') {
self.value = value;
self.status = 'fulfilled';
// fulfilled执行异步的方法
self.onResolvedCallbacks.forEach(function (fn) {
fn();
});
}
}
function reject(reason) {
if (self.status === 'pending') {
self.reason = reason;
self.status = 'rejected';
// rejected执行异步的方法
self.onRejectedCallbacks.forEach(function (fn) {
fn();
});
}
}
try {
executor(resolve, reject); // 跑出异常时,走下一个then的失败
} catch (e) {
reject(e); // 出错,reason就是原因
}
}
Promise.prototype.then = function (onFulFilled, onRejected) {
let self = this;
// 成功后执行onFulFilled返回值
if (self.status === 'fulfilled') {
onFulFilled(self.value);
}
// 失败后执行onRejected返回原因
if (self.status === 'rejected') {
onRejected(self.reason);
}
// 当Promise的executor中有异步方法时
if (self.status === 'pending') {
self.onResolvedCallbacks.push(function () {
onFulFilled(self.value);
})
self.onRejectedCallbacks.push(function () {
onRejected(self.reason);
})
}
}
module.exports = Promise;
Promise源码(三)
- 链式调用
- Promise 中每次调用 then 都应该返回一个新的 Promise。
- Promise 的实例只能成功或者失败,不能既成功又失败。
- promise2
case.js
let Promise = require('./promise');
let p = new Promise(function (resolve, reject) {
resolve('xxx');
})
p.then(function (data) {
console.log(`success ${data}`);
}, function (err) {
console.log(`err ${err}`);
}).then(function (data) {
console.log(`success ${data}`);
}, function (err) {
console.log(`err ${err}`);
})
promise.js
function Promise(executor) {
let self = this;
// 保存Promise状态,默认pending;三个状态: pending, fulfilled 或 rejected.
self.status = 'pending';
// 保存成功的值
self.value = undefined;
// 保存失败的原因
self.reason = undefined;
// 异步方法存起来
self.onResolvedCallbacks = [];
self.onRejectedCallbacks = [];
// 只有Promise状态为pending才能进行转化
function resolve(value) {
if (self.status === 'pending') {
self.value = value;
self.status = 'fulfilled';
// fulfilled执行异步的方法
self.onResolvedCallbacks.forEach(function (fn) {
fn();
});
}
}
function reject(reason) {
if (self.status === 'pending') {
self.reason = reason;
self.status = 'rejected';
// rejected执行异步的方法
self.onRejectedCallbacks.forEach(function (fn) {
fn();
});
}
}
try {
executor(resolve, reject); // 跑出异常时,走下一个then的失败
} catch (e) {
reject(e); // 出错,reason就是原因
}
}
// 核心方法:处理成功或失败执行的返回值,处理promise2的关系;
function resolvePromise(promise2, x, resolve, reject) {
}
Promise.prototype.then = function (onFulFilled, onRejected) {
let self = this;
let promise2;
promise2 = new Promise(function (resolve, reject) {
// 成功后执行onFulFilled返回值
if (self.status === 'fulfilled') {
setTimeout(() => {
try {
// 限制需要做的事情就是把then中成功或者失败后执行的结果获取到
// 判断是否为promise,是promise就让promise执行,取到这个promise的执行结果。
let x = onFulFilled(self.value);
// 判断promise2和x也是then函数返回的结果和promise2的关系,如果x是普通值,让promise2成功;如果是一个失败的promise,直接让promise2失败
resolvePromise(promise2, x, resolve, reject);
} catch (error) {
reject(error);
}
}, 0)
}
// 失败后执行onRejected返回原因
if (self.status === 'rejected') {
setTimeout(() => {
try {
let x = onRejected(self.reason);
resolvePromise(promise2, x, resolve, reject);
} catch (error) {
reject(error);
}
}, 0)
}
// 当Promise的executor中有异步方法时
if (self.status === 'pending') {
self.onResolvedCallbacks.push(function () {
setTimeout(() => {
try {
let x = onFulFilled(self.value);
resolvePromise(promise2, x, resolve, reject);
} catch (error) {
reject(error);
}
}, 0)
})
self.onRejectedCallbacks.push(function () {
setTimeout(() => {
try {
let x = onRejected(self.reason);
resolvePromise(promise2, x, resolve, reject);
} catch (error) {
reject(error);
}
}, 0)
})
}
})
// 调用then后返回一个Promise
return promise2;
}
module.exports = Promise;
Promise源码(四)
- Promise核心方法:处理成功或失败执行的返回值,处理promise2的关系;
- resolvePromise
case.js
let Promise = require('./promise');
let p = new Promise(function (resolve, reject) {
resolve();
})
p.then(function (data) {
// 判断返回的是一个Promise
return new Promise((resolve, reject) => {
resolve(1000);
})
}).then(data => {
console.log(`success ${data}`);
}, err => {
console.log(`err ${err}`)
})
promise.js
function Promise(executor) {
let self = this;
// 保存Promise状态,默认pending;三个状态: pending, fulfilled 或 rejected.
self.status = 'pending';
// 保存成功的值
self.value = undefined;
// 保存失败的原因
self.reason = undefined;
// 异步方法存起来
self.onResolvedCallbacks = [];
self.onRejectedCallbacks = [];
// 只有Promise状态为pending才能进行转化
function resolve(value) {
if (self.status === 'pending') {
self.value = value;
self.status = 'fulfilled';
// fulfilled执行异步的方法
self.onResolvedCallbacks.forEach(function (fn) {
fn();
});
}
}
function reject(reason) {
if (self.status === 'pending') {
self.reason = reason;
self.status = 'rejected';
// rejected执行异步的方法
self.onRejectedCallbacks.forEach(function (fn) {
fn();
});
}
}
try {
executor(resolve, reject); // 跑出异常时,走下一个then的失败
} catch (e) {
reject(e); // 出错,reason就是原因
}
}
// 核心方法:处理成功或失败执行的返回值,处理promise2的关系;
function resolvePromise(promise2, x, resolve, reject) {
// 有可能x===promise2
if (promise2 === x) {
return reject(new TypeError('TypeError: Chaining cycle detected for promise #<Promise>'));
}
// 如果是第三方的Promise
let called; // 文档要求,一旦成功,不能调用失败
if ((x !== null && typeof x === 'object') || typeof x === 'function') {
// x可能是一个promise
try {
// x = {then:function(){}}
let then = x.then; // 取then方法
if (typeof then === 'function') {
then.call(x, function (y) {
if (!called) { called = true; } else { return; }
resolvePromise(x, y, resolve, reject); // 递归检查promise
}, function (r) {
if (!called) { called = true; } else { return; }
reject(r);
});
} else {
resolve(x); // 普通值
}
} catch (error) {
if (!called) { called = true; } else { return; }
reject(error);
}
} else {
// x是普通值,直接返回
resolve(x);
}
}
Promise.prototype.then = function (onFulFilled, onRejected) {
// 判断onFulFilled和onRejected是函数
onFulFilled = typeof onFulFilled === 'function' ? onFulFilled : function (data) {
return data;
}
onRejected = typeof onRejected === 'function' ? onRejected : function (err) {
throw err;
}
let self = this;
let promise2;
promise2 = new Promise(function (resolve, reject) {
// 成功后执行onFulFilled返回值
if (self.status === 'fulfilled') {
setTimeout(() => {
try {
// 限制需要做的事情就是把then中成功或者失败后执行的结果获取到
// 判断是否为promise,是promise就让promise执行,取到这个promise的执行结果。
let x = onFulFilled(self.value);
// 判断promise2和x也是then函数返回的结果和promise2的关系,如果x是普通值,让promise2成功;如果是一个失败的promise,直接让promise2失败
resolvePromise(promise2, x, resolve, reject);
} catch (error) {
reject(error);
}
}, 0)
}
// 失败后执行onRejected返回原因
if (self.status === 'rejected') {
setTimeout(() => {
try {
let x = onRejected(self.reason);
resolvePromise(promise2, x, resolve, reject);
} catch (error) {
reject(error);
}
}, 0)
}
// 当Promise的executor中有异步方法时
if (self.status === 'pending') {
self.onResolvedCallbacks.push(function () {
setTimeout(() => {
try {
let x = onFulFilled(self.value);
resolvePromise(promise2, x, resolve, reject);
} catch (error) {
reject(error);
}
}, 0)
})
self.onRejectedCallbacks.push(function () {
setTimeout(() => {
try {
let x = onRejected(self.reason);
resolvePromise(promise2, x, resolve, reject);
} catch (error) {
reject(error);
}
}, 0)
})
}
})
// 调用then后返回一个Promise
return promise2;
}
// 测试是否符合PromiseA+规范 cnpm i promises-aplus-tests -g
Promise.deferred = Promise.defer = function () {
let dfd = {};
dfd.promise = new Promise((resolve, reject) => {
dfd.resolve = resolve;
dfd.reject = reject;
})
return dfd;
}
module.exports = Promise;