Promise
是异步编程的一种解决方案,比传统的异步解决方案【回调函数】和【事件】更合理、更强大。现已被 ES6 归入进规范中;Promise
解决了“回调地狱”的痛点;Promise.length
length
属性,其值老是为 1 (构造器参数的数目).Promise.prototype
Promise
构造器的原型.Promise.resolve(value)
value
决定的Promise
对象。thenable
(即,带有then
方法的对象),返回的Promise
对象的最终状态由 then 方法执行决定;value
为空,基本类型或者不带then
方法的对象),返回的Promise
对象状态为fulfilled(resolved)
,而且将该value
传递给对应的then
方法;Promise
对象,使用Promise.resolve(value)
来返回一个Promise
对象,这样就能将该value
以Promise
对象形式使用;Promise.reject(reason)
Promise
对象,并将给定的失败信息传递给对应的处理方法Promise.race(iterable)
iterable
参数里的任意一个子promise
被成功或失败后(即第一个执行完的promise
),父promise
立刻也会用子promise
的成功返回值或失败详情做为参数调用父promise
绑定的相应句柄,并返回该promise
对象Promise.allSettled(iterable)
promise
结果Promise.all(iterable)
promise
对象,promise
对象在iterable
参数对象里全部的promise
对象都成功的时候才会触发成功iterable
里面的promise
对象失败则当即触发该promise
对象的失败promise
对象在触发成功状态之后,会把一个包含iterable
里全部promise
返回值的数组做为成功回调的返回值,顺序跟iterable
的顺序保持一致;promise
对象触发了失败状态,它会把iterable
里第一个触发失败的promise
对象的错误信息做为它的失败错误信息。Promise.all
方法常被用于处理多个promise
对象的状态集合。Promise.prototype.constructor
Promise
函数Promise.prototype.then(onFulfilled, onRejected)
fulfillment
)和拒绝(rejection
)回调到当前 promise
, 返回一个新的 promise
, 将以回调的返回值来 resolve
;onFulfilled
中抛出的异常;Promise.prototype.catch(onRejected)
rejection
) 回调到当前 promise
, 返回一个新的promise
。promise
将以它的返回值来 resolve,不然若是当前promise
进入fulfilled
状态,则以当前promise
的完成结果做为新promise
的完成结果.Promise.prototype.finally(onFinally)
promise
对象,而且在原promise
对象解析完毕后,返回一个新的promise
对象。promise
运行完毕后被调用,不管当前promise
的状态是完成(fulfilled
)仍是失败(rejected
)• process.nextTick
和 promise.then
都属于 微任务(microtask
),而 setImmediate
、setTimeout
、setInterval
属于 宏任务(macrotask
),事件循环先执行宏任务,再执行全部微任务 • Promise
构造函数是同步执行的,promise.then
中的函数是异步执行的javascript
const promise = new Promise((resolve, reject) => {
// 构造函数同步执行
console.log(1);
resolve();
console.log(2);
});
promise.then(() => {
// 异步执行
console.log(3);
});
console.log(4);
// ------------执行结果-------------
1;
2;
4;
3;
复制代码
promise
有 3 种状态:pending
、resolved(fulfilled)
或 rejected
。状态改变只能是 pending
->resolved
或者 pending
->rejected
,状态一旦改变则不能再变。
pending
: 初始状态,既不是成功,也不是失败状态。resolved
(fulfilled
): 意味着操做成功完成。rejected
: 意味着操做失败。const p1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('success')
}, 1000)
});
const p2 = promise1.then(() => {
throw new Error('error!!!')
});
console.log('promise1', p1);
console.log('promise2', p2);
setTimeout(() => {
console.log('promise1', p1)
console.log('promise2', p2)
}, 2000);
// ------------执行结果-------------
promise1 Promise {<pending>}
promise2 Promise {<pending>}
Uncaught (in promise) Error: error!!!
at <anonymous>:7:9
Promise.then (async)
promise1 Promise {<resolved>: "success"}
promise2 Promise {<rejected>: Error: error!!!
at <anonymous>:7:9}
复制代码
resolve
或 reject
只有第一次执行有效,屡次调用没有任何做用new Promise((resolve, reject) => {
resolve("resolve1");
reject("reject");
resolve("resolve2");
})
.then((res) => {
console.log("then: ", res);
})
.catch((err) => {
console.log("catch: ", err);
});
// ------------执行结果-------------
then: resolve1;
复制代码
promise
每次调用 .then
或者.catch
都会返回一个新的 promise
,从而实现了链式调用const p1 = Promise.resolve(1); // 返回 Promise
// 返回 Promise
const p2 = p1
.then((res) => {
console.log(res);
return 2;
})
.catch((err) => {
return 3;
});
// 返回 Promise
const p3 = p2.then((res) => {
console.log(res);
});
// ------------执行结果-------------
1;
2;
复制代码
promise
的 .then
或者 .catch
能够被调用屡次,但这里 Promise
构造函数只执行一次。
promise
内部状态一经改变,而且有了一个值,那么后续每次调用 .then
或者 .catch
都会直接拿到该值const p5 = new Promise((resolve, reject) => {
// 构造函数只执行一次
setTimeout(() => {
console.log('start')
resolve('success'); // 第一次生效
resolve('success1'); // 执行无效
}, 1000)
})
p5.then((res) => {
console.log('promise1', res);
});
p5.then((res) => {
console.log('promise2', res)
});
// ------------执行结果-------------
start
promise1 success
promise2 success
复制代码
.then
能够接收两个参数,第一个是处理成功的函数,第二个是处理错误的函数。
.catch
是 .then
第二个参数的简便写法;.then
的第二个处理错误的函数捕获不了第一个处理成功的函数抛出的错误,然后续的 .catch
能够捕获以前的错误Promise.resolve().then(function success1 (res) {
throw new Error('error'); // 第一个 then 抛出 error 下一个 then 才能接收
}, function fail1 (e) {
console.error('error1: ', e)
}).then(function success2 (res) {}, function fail2 (e) {
// 接收上一个 then 抛出的 error
console.error('error2: ', e)
});
// ------------执行结果-------------
error2: Error: error
at success1 (<anonymous>:2:11) 复制代码
.then
或者 .catch
的参数指望是函数,传入非函数则会发生值穿透Promise.resolve(1)
.then(2) // 这一步会穿透
.then(Promise.resolve(3)) // 这里 Promise.resolve(3) 为 Promise 对象,这一步也会穿透
.then(console.log); // 这里接收到第一次 resolve 的 1
// ------------执行结果-------------
1;
复制代码
function Promise(fn) {}
// 中断抛出结果集
Promise.resolve = function (value) {};
// 中断抛出异常
Promise.reject = function (reason) {};
// 返回多个promise集合请求中最快返回的结果
Promise.race = function (iterable) {};
// 返回多个promise集合全部不论正常或者异常的结果集
Promise.allSettled = function (iterable) {};
// 返回多个promise集合全部正常的结果集,有错误则中断返回该错误结果
Promise.all = function (iterable) {};
// 原型方法 then, 返回新的promise造成链式调用
Promise.prototype.then = function (onResolved, onRejected) {};
// 原型方法 catch, 抛出异常
Promise.prototype.catch = function (onError) {};
// 原型方法 promise 正常或者异常以后的最后一次处理
Promise.prototype.finally = function (onFinally) {};
复制代码
function resolve(value) {
var _this = this;
// 状态不为 pending 则不执行,这里避免屡次触发
if (_this._status !== "pending") return;
setTimeout(function () {
_this._status = "fulfilled";
_this._value = value;
_this._onResolvedFns.forEach(function (cb) {
cb && cb();
});
});
}
function reject(error) {
var _this = this;
// 状态不为 pending 则不执行,这里避免屡次触发
if (_this._status !== "pending") return;
setTimeout(function () {
_this._status = "rejected";
_this._error = error;
_this._onRejectedFns.forEach(function (cb) {
cb && cb();
});
});
}
function isFunction(func) {
return typeof func === "function";
}
function isObject(func) {
return typeof func === "object";
}
function Promise(fn) {
if (!isObject(this)) {
throw new TypeError("Promise 必须是 new 实例化的对象");
}
if (!isFunction(fn)) {
throw new TypeError("Promise 构造函数入参必须是函数");
}
// 状态 pending/fulfilled/rejected
this._status = "pending"; // 默认 pending
this._value = null; // 值
this._error = null; // 异常
// 成功的回调
this._onResolvedFns = [];
// 失败的回调
this._onRejectedFns = [];
try {
// 绑定当前上下文
fn(resolve.bind(this), reject.bind(this));
} catch (e) {
reject(e);
}
}
复制代码
Promise.prototype.then
链式回调/** * 解析 promise * 若回调为 promise 实例,则继续流式解析 * * @param {*} promise * @param {*} result 回调结果 * @param {*} resolve * @param {*} reject */
function resolvePromise(promise, result, resolve, reject) {
// 循环引用检测
if (promise === result) return reject(new TypeError("循环引用"));
if (result instanceof Promise) {
result.then(function (newResult) {
resolvePromise(promise, newResult, resolve, reject);
}, reject);
} else if (isObject(result) || isFunction(result)) {
if (result === null) return resolve(result);
var then;
try {
then = result.then;
} catch (error) {
return reject(error);
}
if (!isFunction(then)) return resolve(result);
var called = false; // 调用锁
try {
var _thenLock = function (cb) {
// 防止再次调用
if (called) return;
called = true; // 标记锁
cb && cb();
};
// then 流式调用
then.call(
result,
function (nextResult) {
_thenLock(function () {
resolvePromise(promise, nextResult, resolve, reject);
});
},
function (r) {
//只要失败了就失败了
_thenLock(function () {
reject(r);
});
}
);
} catch (e) {
_thenLock(function () {
reject(e);
});
}
} else {
resolve(result);
}
}
// 原型方法 then, 返回新的promise造成链式调用
Promise.prototype.then = function (onResolved, onRejected) {
// then 接收两个函数,若果不是函数则直接形成值穿透,即上一个 then 的值继续向下走
onResolved = isFunction(onResolved)
? onResolved
: function (y) {
return y;
};
onRejected = isFunction(onRejected)
? onRejected
: function (err) {
throw err;
};
var _this = this;
var promise = new Promise(function (resolve, reject) {
if (_this._status === "pending") {
// pending 状态
// 存放成功回调
_this._onResolvedFns.push(function () {
setTimeout(function () {
try {
resolvePromise(promise, onResolved(_this._value), resolve, reject);
} catch (error) {
reject(error);
}
});
});
// 存放失败的回调
_this._onRejectedFns.push(function () {
setTimeout(function () {
try {
resolvePromise(promise, onRejected(_this._error), resolve, reject);
} catch (error) {
reject(error);
}
});
});
} else {
setTimeout(function () {
try {
// fulfilled / rejected 状态 解析回调
resolvePromise(
promise,
_this._status === "fulfilled"
? onResolved(_this._value)
: onRejected(_this._error),
resolve,
reject
);
} catch (error) {
reject(error);
}
});
}
});
return promise;
};
复制代码
Promise.prototype.catch
异常捕获// 原型方法 catch, 抛出异常
Promise.prototype.catch = function (onError) {
// catch 方法就是then方法没有成功的简写
return this.then(null, onError);
};
复制代码
Promise.prototype.finally
结束调用// 原型方法 promise 正常或者异常以后的最后一次处理
Promise.prototype.finally = function (onFinally) {
var _finally = Promise.resolve(onFinally());
return this.then(
function (value) {
return _finally.then(function () {
return value;
});
},
function (error) {
return _finally.then(function () {
throw error;
});
}
);
};
复制代码
Promise.resolve
// 中断抛出结果集
Promise.resolve = function (value) {
return new Promise(function (resolve) {
resolve(value);
});
};
复制代码
Promise.reject
// 中断抛出异常
Promise.reject = function (reason) {
return new Promise(function (resolve, reject) {
reject(reason);
});
};
复制代码
Promise.all
// 返回多个promise集合全部正常的结果集,有错误则中断返回该错误结果
Promise.all = function (iterable) {
return new Promise(function (resolve, reject) {
var array = Array.prototype.slice.call(iterable);
if (!array.length) return resolve([]);
var results = [];
var count = 0;
for (var i = 0; i < array.length; i++) {
(function (i) {
Promise.resolve(array[i])
.then(function (res) {
results[i] = res;
count++;
if (count === array.length) {
resolve(results);
}
})
.catch(function (error) {
reject(error);
});
})(i);
}
});
};
复制代码
Promise.race
// 返回多个promise集合请求中最快返回的结果
Promise.race = function (iterable) {
return new Promise(function (resolve, reject) {
// 浅拷贝
var array = Array.prototype.slice.call(iterable);
for (var i = 0; i < array.length; i++) {
Promise.resolve(array[i]).then(resolve, reject);
}
});
};
复制代码
Promise.allSettled
// 返回多个promise集合全部不论正常或者异常的结果集
Promise.allSettled = function (iterable) {
return new Promise(function (resolve, reject) {
var array = Array.prototype.slice.call(iterable);
if (!array.length) return resolve([]);
var results = [];
var count = 0;
for (var i = 0; i < array.length; i++) {
(function (i) {
Promise.resolve(array[i]).finally(function (value) {
results[i] = res;
count++;
if (count === array.length) {
resolve(results);
}
});
})(i);
}
});
};
复制代码
Promise/A+
测试promises-tests
测试包promise.spec.js
var Promise = require("./promise");
Promise.deferred = function () {
var result = {};
result.promise = new Promise(function (resolve, reject) {
result.resolve = resolve;
result.reject = reject;
});
return result;
};
module.exports = Promise;
复制代码
promises-tests promise.spec.js
function resolve(value) {
var _this = this;
// 状态不为 pending 则不执行,这里避免屡次触发
if (_this._status !== "pending") return;
setTimeout(function () {
_this._status = "fulfilled";
_this._value = value;
_this._onResolvedFns.forEach(function (cb) {
cb && cb();
});
});
}
function reject(error) {
var _this = this;
// 状态不为 pending 则不执行,这里避免屡次触发
if (_this._status !== "pending") return;
setTimeout(function () {
_this._status = "rejected";
_this._error = error;
_this._onRejectedFns.forEach(function (cb) {
cb && cb();
});
});
}
function isFunction(func) {
return typeof func === "function";
}
function isObject(func) {
return typeof func === "object";
}
/** * 解析 promise * 若回调为 promise 实例,则继续流式解析 * * @param {*} promise * @param {*} result 回调结果 * @param {*} resolve * @param {*} reject */
function resolvePromise(promise, result, resolve, reject) {
// 循环引用检测
if (promise === result) return reject(new TypeError("循环引用"));
if (result instanceof Promise) {
result.then(function (newResult) {
resolvePromise(promise, newResult, resolve, reject);
}, reject);
} else if (isObject(result) || isFunction(result)) {
if (result === null) return resolve(result);
var then;
try {
then = result.then;
} catch (error) {
return reject(error);
}
if (!isFunction(then)) return resolve(result);
var called = false; // 调用锁
try {
var _thenLock = function (cb) {
// 防止再次调用
if (called) return;
called = true; // 标记锁
cb && cb();
};
// then 流式调用
then.call(
result,
function (nextResult) {
_thenLock(function () {
resolvePromise(promise, nextResult, resolve, reject);
});
},
function (r) {
//只要失败了就失败了
_thenLock(function () {
reject(r);
});
}
);
} catch (e) {
_thenLock(function () {
reject(e);
});
}
} else {
resolve(result);
}
}
function Promise(fn) {
if (!isObject(this)) {
throw new TypeError("Promise 必须是 new 实例化的对象");
}
if (!isFunction(fn)) {
throw new TypeError("Promise 构造函数入参必须是函数");
}
// 状态 pending/fulfilled/rejected
this._status = "pending"; // 默认 pending
this._value = null; // 值
this._error = null; // 异常
// 成功的回调
this._onResolvedFns = [];
// 失败的回调
this._onRejectedFns = [];
try {
// 绑定当前上下文
fn(resolve.bind(this), reject.bind(this));
} catch (e) {
reject(e);
}
}
// 原型方法 then, 返回新的promise造成链式调用
Promise.prototype.then = function (onResolved, onRejected) {
// then 接收两个函数,若果不是函数则直接形成值穿透,即上一个 then 的值继续向下走
onResolved = isFunction(onResolved)
? onResolved
: function (y) {
return y;
};
onRejected = isFunction(onRejected)
? onRejected
: function (err) {
throw err;
};
var _this = this;
var promise = new Promise(function (resolve, reject) {
if (_this._status === "pending") {
// pending 状态
// 存放成功回调
_this._onResolvedFns.push(function () {
setTimeout(function () {
try {
resolvePromise(promise, onResolved(_this._value), resolve, reject);
} catch (error) {
reject(error);
}
});
});
// 存放失败的回调
_this._onRejectedFns.push(function () {
setTimeout(function () {
try {
resolvePromise(promise, onRejected(_this._error), resolve, reject);
} catch (error) {
reject(error);
}
});
});
} else {
setTimeout(function () {
try {
// fulfilled / rejected 状态 解析回调
resolvePromise(
promise,
_this._status === "fulfilled"
? onResolved(_this._value)
: onRejected(_this._error),
resolve,
reject
);
} catch (error) {
reject(error);
}
});
}
});
return promise;
};
// 原型方法 catch, 抛出异常
Promise.prototype.catch = function (onError) {
// catch 方法就是then方法没有成功的简写
return this.then(null, onError);
};
// 原型方法 promise 正常或者异常以后的最后一次处理
Promise.prototype.finally = function (onFinally) {
var _finally = Promise.resolve(onFinally());
return this.then(
function (value) {
return _finally.then(function () {
return value;
});
},
function (error) {
return _finally.then(function () {
throw error;
});
}
);
};
// 中断抛出结果集
Promise.resolve = function (value) {
return new Promise(function (resolve) {
resolve(value);
});
};
// 中断抛出异常
Promise.reject = function (reason) {
return new Promise(function (resolve, reject) {
reject(reason);
});
};
// 返回多个promise集合请求中最快返回的结果
Promise.race = function (iterable) {
return new Promise(function (resolve, reject) {
// 浅拷贝
var array = Array.prototype.slice.call(iterable);
for (var i = 0; i < array.length; i++) {
Promise.resolve(array[i]).then(resolve, reject);
}
});
};
// 返回多个promise集合全部不论正常或者异常的结果集
Promise.allSettled = function (iterable) {
return new Promise(function (resolve, reject) {
var array = Array.prototype.slice.call(iterable);
if (!array.length) return resolve([]);
var results = [];
var count = 0;
for (var i = 0; i < array.length; i++) {
(function (i) {
Promise.resolve(array[i]).finally(function (value) {
results[i] = res;
count++;
if (count === array.length) {
resolve(results);
}
});
})(i);
}
});
};
// 返回多个promise集合全部正常的结果集,有错误则中断返回该错误结果
Promise.all = function (iterable) {
return new Promise(function (resolve, reject) {
var array = Array.prototype.slice.call(iterable);
if (!array.length) return resolve([]);
var results = [];
var count = 0;
for (var i = 0; i < array.length; i++) {
(function (i) {
Promise.resolve(array[i])
.then(function (res) {
results[i] = res;
count++;
if (count === array.length) {
resolve(results);
}
})
.catch(function (error) {
reject(error);
});
})(i);
}
});
};
module.exports = Promise;
复制代码
以上是对 promise 的学习纪要,但愿可以帮助到你们,若有不对的地方,但愿你们不吝指正,谢谢。java