预备知识
- 函数对象与实例对象
函数对象:将函数作为对象使用,简称为函数对象
实例对象:new 函数产生对象,简称为对象
- 回调函数的分类
- 同步回调
立即执行,完全执行完了才结束,不会放入回调队列中
例子: 数组遍历相关的回调函数/Promise的excutor函数 - 异步回调
理解: 不会立即执行,会放入回调队列中将来执行
例子: 定时器回调/ajax回调/Promise的成功|失败回调
- js错误和错误处理
- 错误类型
Error: 所有错误的父类型
ReferenceError: 引用变量不存在
TypeError: 数据类型不正确的错误
RangeRrror: 数据值不在其所允许的范围内
SyntaxError: 语法错误 - 错误处理
捕获错误: try ... catch
抛出错误: throw error //让调用者处理异常 - 错误对象
message属性: 错误相关信息
stack属性: 函数调用栈的记录
promise认知
- promise是什么?
- 抽象表达: Promise是js中进行异步编程的新解决方案(旧的是谁)
- 具体表达: 语法上:Promise是一个构造函数;功能上对象用来封装一个异步操作并可以获取其结果
- 为什么要用?好处
-
指定回调函数的方式更加灵活:
旧的:必须在启动异步任务前指定
promise:启动异步任务 =》 返回promise对象 =》 给promise对象绑 定回调函数 -
支持链式调用,可以解决回调地狱问题
什么是回调地狱? 回调函数嵌套调用,外部回调函数异步执行的结果是嵌套的回调函数执行的条件
回调地狱的缺点? 不便于阅读/不利于异常处理
同步编码方式去编写异步代码 -
回调地狱解决方案?
promise ? promise 链式调用
async/await?终极解决方案
async await
-
async函数
函数的返回值为promise对象
promise对象的结果由async函数执行返回值 -
await 表达式
await右侧表达式一般为promise对象,但也可以是其它的值
如果表达式是promise对象,await 返回的是promise成功的值
如果表达式是其他值,直接将此值作为await的返回值 -
注意:
await 必须写在async 函数中, 但async 函数中可以没有await
如果await的promise失败了,就会抛出异常,需要通过try...catch 来捕获异常处理
手写promise
(function (window) {
const PENDING = "pending";
const RESOLVED = "resolved";
const REJECTED = "rejected";
function Promise(excutor) {
const _this = this;
_this.status = PENDING;
_this.data = undefined;
_this.callbacks = []//
//3件事
//1. 改变状态
//2. 保存返回值
//3. 异步执行 成功的回调函数 就是在 队列中执行
function resolve(value) {
if (value == PENDING) {
return
}
_this.status = RESOLVED;
_this.data = value;
if (_this.callbacks.length > 0) {
_this.callbacks.forEach(callback => {
setTimeout(() => {
callback.onResolved(_this.data);
})
})
}
}
function reject(reason) {
if (value == PENDING) {
return
}
_this.status = REJECTED;
_this.data = reason;
if (_this.callbacks.length > 0) {
_this.callbacks.forEach(callback => {
setTimeout(() => {
callback.onRejected(_this.data);
})
})
}
}
try {
excutor(resolve, reject);
} catch (error) {
reject(error);
}
}
Promise.prototype.then = function (onResolved, onRjected) {
// 两个默认功能
onResolved = typeof onResolved == "function"? onResolved : value => value;
onRjected = typeof onRjected == "function"? onRjected : reason => { throw reason };
const _this = this;
return new Promise((resolve, reject) => {
//3中情况
//1. 回调函数返回值 抛出异常, 这个return promise对象是失败状态,失败的原因数据是reason
//2. 回调函数返回值 是 非 promise, return promise对象是成功状态,成功的值 是value
//3. 回调函数反正值 是 promise对象, return promise对象的状态和数据由当前promise对象决定
function handle(callback) {
try {
let reuslt = callback(_this.data);
if(reuslt instanceof Promise) {
reuslt.then(
value => {
resolve(value);
},
reason => {
reject(reason);
}
)
}else {
resolve(_this.data);
}
} catch (error) {
reject(error)
}
}
if (_this.status == PENDING) {
_this.callback.push({
onResolved: function () {
handle(onResolved)
},
onRjected: function () {
handle(onRjected)
}
})
} else if (_this.status == RESOLVED) {
setTimeout(() => {
handle(onResolved)
});
} else {
setTimeout(() => {
handle(onRjected)
});
}
})
}
// 1. 返回一个promise, 2. 回调函数是失败的回调函数
Promise.prototype.catch = function(onRejected) {
return this.then(undefined, onRejected)
}
//1.返回一个promise, 2 回调函数的成功和失败 与 类型有关
Promise.resolve = function(value) {
return new Promise((resolve,reject) => {
if(value instanceof Promise) {
value.then(
value2 => {resolve(value2)},
reason2 => {reject(reason2)}
)
}else {
reject(value)
}
})
}
//1. 返回一个promise, 2. 回调函数一定失败
Promise.reject = function(reason) {
return new Promise((resolve,reject) => {
reject(reason)
})
}
//1. 返回一个promise, 2.所有的promises 成功后 才返回成功,成功值 是一个数组
Promise.all = function(promises) {
return new Promise((resolve,reject) => {
let values = [];
let count = 0;
promises.forEach((p,index) => {
p.then(
value => {
count ++;
values[index] = value;
if(count == promises.length) {
resolve(values);
}
},
reason => {
reject(reason);
}
)
})
})
}
//1. 返回一个promise对象, 2.返回 最先执行成功的promise, 返回成功值value
Promise.race = function(promise) {
return new Promise((resolve,reject) => {
promise.forEach(p => {
p.then(
value => {
resolve(value)
},
reason => {
reject(reason)
}
)
})
})
}
window.Promise = Promise;
})(window)
网友评论