Appearance
💘Promise
准备
函数对象与实例对象
- 函数对象: 将函数作为对象使用时, 简称为函数对象
- 实例对象: new 函数产生的对象, 简称为对象
回调函数的分类
- 同步回调: 理解: 立即执行, 完全执行完了才结束, 不会放入回调队列中 例子: 数组遍历相关的回调函数 / Promise的excutor函数
- 异步回调: 理解: 不会立即执行, 会放入回调队列中将来执行 例子: 定时器回调 / ajax回调 / Promise的成功|失败的回调
JS中的Error
- 错误的类型 Error: 所有错误的父类型 ReferenceError: 引用的变量不存在 TypeError: 数据类型不正确的错误 RangeError: 数据值不在其所允许的范围内 SyntaxError: 语法错误
- 错误处理 捕获错误: try ... catch 抛出错误: throw error
- 错误对象 message属性: 错误相关信息 stack属性: 函数调用栈记录信息
理解
Promise 是 JS 中进行异步编程的新的解决方案(旧的是谁?单纯的回调函数)
具体表达:
(1) 从语法上来说: Promise 是一个构造函数
(2) 从功能上来说: promise 对象用来封装一个异步操作并可以获取其结果
异步编程:fs文件操作、数据库操作、AJAX、定时器
为什么要用promise?
- 指定回调函数的方式更加灵活
- 支持
链式调用
, 可以解决回调地狱问题- 解决方案:promise 链式调用
- 终极解决方案: async/await
初体验
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div class="container">
<h2 class="page-header">promise 初体验</h2>
<button class="btn btn-primary" id="btn">点击抽奖</button>
</div>
<script>
// 生成随机数
function rand(m, n) {
return Math.ceil(Math.random() * (n - m + 1)) + m - 1;
}
// 获取元素对象
const btn = document.querySelector("#btn");
// 绑定单击事件
btn.addEventListener("click", function () {
// 定时器
// setTimeout(() => {
// // 30%中奖概率
// // 获取从1~100的一个随机数
// let n = rand(1, 100);
// // 判断
// if (n <= 30) {
// alert("恭喜您获得宝马5RMB优惠券!您的中奖数字为:");
// } else {
// alert("再接再厉!您的号码为:");
// }
// }, 1000);
// promise形式实现 必须要接受的参数要是函数类型的值
// resolve 解决 函数类型的数据
// reject 拒绝 函数类型的数据
const p = new Promise((resolve, reject) => {
setTimeout(() => {
// 30%中奖概率
// 获取从1~100的一个随机数
let n = rand(1, 100);
// 判断
if (n <= 30) {
resolve(n); // 将promise对象的状态设置为成功
} else {
reject(n); // 将promise对象的状态设置为失败
}
}, 1000);
});
// 调用then方法 要接受的参数都是函数类型的值
// value、reason在这里是默认的规则;可以替换为其他名字
p.then(
(value) => {
// 成功执行的函数
alert("恭喜您获得宝马5RMB优惠券!您的中奖数字为:" + value);
},
(reason) => {
// 失败执行的函数
alert("再接再厉!您的号码为:" + reason);
}
);
});
</script>
</body>
</html>
封装fs读取文件操作
js
/**
* 封装一个函数 mineReadFile 读取文件内容
* 参数:path 文件路径
* 回调:promise 对象
*/
function mineReadFile(path){
return new Promise((resolve, reject) => {
// 读取文件
require('fs').readFile(path, (err, data) => {
// 判断
if(err) reject();
// 成功
resolve();
})
})
}
mineReadFile('./resource/fs.txt')
.then(value=>{
// 输出文件内容
console.log(value.toString());
}, reason=>{
console.log(reason);
});
promisify
将代码进行promise风格转化
js
/**
* until.promisify 方法
*/
// 引入util模块
const util = require('util');
// 引入fs模块
const fs = require('fs');
// 返回一个新的函数
let mineReadFile = util.promisify(fs.readFile);
mineReadFile('./resource/main.txt').then(value=>{
console.log(value.toString());
});
ajax封装
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>promise封装ajax操作</title>
</head>
<body>
<script>
/**
* 封装一个函数 sendAJAX 发送 GET AJAX请求
* 参数 url
* 返回结果 promise对象
*/
function sendAJAX(url) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.responseType = "json";
xhr.open("GET", url);
xhr.send();
// 处理结果
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
// 状态码判断
if (xhr.status >= 200 && xhr.status < 300) {
// 成功的结果
resolve(xhr.response);
} else {
// 失败的结果
reject(xhr.status);
}
}
};
});
}
sendAJAX("https://api.apiopen.top/getJoke").then(
(value) => {
console.log(value);
},
(reason) => {
console.log(reason);
}
);
</script>
</body>
</html>
Promise状态
实例对象中的一个属性 [PromiseState]
- pending 未决定的
- resolved / fullfilled 成功
- rejected 失败
状态改变只有两种:pending --> resolved pending --> rejected;并且只能改变一次,无论成功或者失败都会有一个结果数据;成功数据一般为value,失败的结果数据一般为reason
Promise对象的值
实例对象中的一个属性 [PromiseResult]
存储对象成功/失败的结果,可以在以下函数中进行值修改:
- resolve
- reject
如何使用Promise?
API
Promise 构造函数: Promise (excutor) {}
(1) excutor 函数: 执行器 (resolve, reject) => {}
(2) resolve 函数: 内部定义成功时我们调用的函数 value => {}
(3) reject 函数: 内部定义失败时我们调用的函数 reason => {}
说明: excutor 会在 Promise 内部立即同步回调,异步操作在执行器中执行
Promise.prototype.then 方法: (onResolved, onRejected) => {}
(1) onResolved 函数: 成功的回调函数 (value) => {}
(2) onRejected 函数: 失败的回调函数 (reason) => {}
说明: 指定用于得到成功 value 的成功回调和用于得到失败 reason 的失败回调 返回一个新的 promise 对象
Promise.prototype.catch方法: (onRejected) => {} onRejected函数: 失败的回调函数 (reason) => {} 说明: then()的语法糖, 相当于: then(undefined, onRejected)
Promise.resolve方法: (value) => {} value: 成功的数据或promise对象 说明: 返回一个成功/失败的promise对象
Promise.reject方法: (reason) => {} reason: 失败的原因 说明: 返回一个失败的promise对象
Promise.all方法: (promises) => {} promises: 包含n个promise的数组 说明: 返回一个新的promise, 只有所有的promise都成功才成功, 只要有一个失败了就直接失败
Promise.race方法: (promises) => {} promises: 包含n个promise的数组 说明: 返回一个新的promise, 第一个完成的promise的结果状态就是最终的结果状态
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>06_Promise的API</title>
</head>
<body>
<script>
let p = new Promise((reslove, reject) => {
// 同步调用
// console.log(111);
// 修改 promise 对象的状态
reject("error");
});
// console.log(222);
p.catch((reason) => {
console.log(reason);
});
//
let p1 = Promise.resolve(521);
// 如果传入的参数为非promise类型的对象,则返回的结果为成功promise对象
// 如果传入的参数为promise类型的对象,则参数的结果决定了 resolve 的结果
let p2 = Promise.resolve(
new Promise((reslove, reject) => {
// reslove("ok");
reject("Error");
})
);
// 对打印p2时出现:Uncaught (in promise) Error 的解决方法 失败promise没有对应的回调函数
p2.catch((reason) => {
console.log(reason);
});
// 无论传入的参数是否为任何类型,返回的状态都是失败的状态,失败的值为传入的值
let p3 = Promise.reject(521);
// all方法:若全部为成功的promise对象,则会返回成功的promise对象(属性值为全部成功对象的属性值);
// 如果有一个失败则会返回该失败的对象(属性值为失败对象的属性值),类似于逻辑与的功能
let p4 = new Promise((resolve, reject) => {
resolve("ok");
});
let p5 = new Promise.resolve("Success");
let p6 = new Promise.resolve("oh yeah");
const result = Promise.all([p4, p5, p6]);
// race方法:返回第一个成功promise对象的属性值
let p7 = new Promise((resolve, reject) => {
resolve("ok");
});
let p8 = new Promise.resolve("Success");
let p9 = new Promise.resolve("oh yeah");
const result1 = Promise.race([p7, p8, p9]);
console.log(p1);
console.log(p2);
console.log(p3);
console.log(result);
console.log(result1);
/*
1. Promise构造函数: Promise (excutor) {}
excutor函数: 同步执行 (resolve, reject) => {}
resolve函数: 内部定义成功时我们调用的函数 value => {}
reject函数: 内部定义失败时我们调用的函数 reason => {}
说明: excutor会在Promise内部立即同步回调,异步操作在执行器中执行
2. Promise.prototype.then方法: (onResolved, onRejected) => {}
onResolved函数: 成功的回调函数 (value) => {}
onRejected函数: 失败的回调函数 (reason) => {}
说明: 指定用于得到成功value的成功回调和用于得到失败reason的失败回调
返回一个新的promise对象
3. Promise.prototype.catch方法: (onRejected) => {}
onRejected函数: 失败的回调函数 (reason) => {}
说明: then()的语法糖, 相当于: then(undefined, onRejected)
4. Promise.resolve方法: (value) => {}
value: 成功的数据或promise对象
说明: 返回一个成功/失败的promise对象
5. Promise.reject方法: (reason) => {}
reason: 失败的原因
说明: 返回一个失败的promise对象
6. Promise.all方法: (promises) => {}
promises: 包含n个promise的数组
说明: 返回一个新的promise, 只有所有的promise都成功才成功, 只要有一个失败了就直接失败
7. Promise.race方法: (promises) => {}
promises: 包含n个promise的数组
说明: 返回一个新的promise, 第一个完成的promise的结果状态就是最终的结果状态
*/
</script>
</body>
</html>
几个关键问题
如何改变 promise 的状态?
(1) resolve(value): 如果当前是 pendding 就会变为 resolved
(2) reject(reason): 如果当前是 pendding 就会变为 rejected
(3) 抛出异常: 如果当前是 pendding 就会变为 rejected
一个 promise 指定多个成功/失败回调函数, 都会调用吗?
当 promise 改变为对应状态时都会调用
改变 promise 状态和指定回调函数谁先谁后?
(1) 都有可能, 正常情况下是先指定回调再改变状态, 但也可以先改状态再指定回调
(2) 如何先改状态再指定回调?
- 在执行器中直接调用 resolve()/reject()
- 延迟更长时间才调用 then()
(3) 什么时候才能得到数据?
- 如果先指定的回调, 那当状态发生改变时, 回调函数就会调用, 得到数据
- 如果先改变的状态, 那当指定回调时, 回调函数就会调用, 得到数据
promise.then()返回的新 promise 的结果状态由什么决定?
(1) 简单表达: 由 then()指定的回调函数执行的结果决定
(2) 详细表达:
- 如果抛出异常, 新 promise 变为 rejected, reason 为抛出的异常
- 如果返回的是非 promise 的任意值, 新 promise 变为 resolved, value 为返回的值
- 如果返回的是另一个新 promise, 此 promise 的结果就会成为新 promise 的结果
promise 如何串连多个操作任务?
(1) promise 的 then()返回一个新的 promise, 可以开成 then()的链式调用
(2) 通过 then 的链式调用串连多个同步/异步任务
promise 异常传透?
(1) 当使用 promise 的 then 链式调用时, 可以在最后指定失败的回调,
(2) 前面任何操作出了异常, 都会传到最后失败的回调中处理
中断 promise 链?
(1) 当使用 promise 的 then 链式调用时, 在中间中断, 不再调用后面的回调函数
(2) 办法: 在回调函数中返回一个 pendding 状态的 promise 对象
1、2:
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>promise的几个关键问题</title>
</head>
<body>
<script>
/*
1. 如何改变promise的状态?
(1)resolve(value): 如果当前是pendding就会变为resolved
(2)reject(reason): 如果当前是pendding就会变为rejected
(3)抛出异常: 如果当前是pendding就会变为rejected
2. 一个promise指定多个成功/失败回调函数, 都会调用吗?
当promise改变为对应状态时都会调用
*/
let p = new Promise((resolve, reject) => {
// 调用resolve函数
resolve("ok"); // pending --> resolved
// 调用reject函数
// reject("Error"); // pending --> rejected
// throw "出问题了!";
});
// 指定回调 - 1
p.then((value) => {
console.log(value);
});
// 指定回调 - 2
p.then((value) => {
alert(value);
});
console.log(p);
</script>
</body>
</html>
3:
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>promise的几个关键问题</title>
</head>
<body>
<script>
/*
3.改变promise状态和指定回调函数谁先谁后?
(1)都有可能, 正常情况下是先指定回调再改变状态, 但也可以先改状态再指定回调
(2)如何先改状态再指定回调?
①在执行器中直接调用resolve()/reject()
②延迟更长时间才调用then()
(3)什么时候才能得到数据?
①如果先指定的回调, 那当状态发生改变时, 回调函数就会调用, 得到数据
②如果先改变的状态, 那当指定回调时, 回调函数就会调用, 得到数据
*/
let p = new Promise((resolve, reject) => {
// resolve('ok');
setTimeout(() => {
resolve("ok");
}, 1000);
});
p.then(
(value) => {
console.log(value);
},
(reason) => {}
);
</script>
</body>
</html>
4:
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>promise的几个关键问题</title>
</head>
<body>
<script>
/*
4. promise.then()返回的新promise的结果状态由什么决定?
(1)简单表达: 由then()指定的回调函数执行的结果决定
(2)详细表达:
①如果抛出异常, 新promise变为rejected, reason为抛出的异常
②如果返回的是非promise的任意值, 新promise变为resolved, value为返回的值
③如果返回的是另一个新promise, 此promise的结果就会成为新promise的结果
*/
let p = new Promise((resolve, reject) => {
resolve("ok");
});
// 执行then方法
let result = p.then(
(value) => {
// console.log(value);
// 抛出错误 状态为失败
// throw "出了问题!";
// 返回结果是一个非promise类型的对象 状态为成功
// return 123;
// 返回的结果是一个promise类型对象 状态取决于promise对象的状态
return new Promise((resolve, reject) => {
// resolve("success");
reject("error");
});
},
(reason) => {
console.log(reason);
}
);
console.log(result);
</script>
</body>
</html>
5:
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>promise的几个关键问题</title>
</head>
<body>
<script>
/*
5.promise如何串连多个操作任务?
(1)promise的then()返回一个新的promise, 可以开成then()的链式调用
(2)通过then的链式调用串连多个同步/异步任务
*/
let p = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("ok");
}, 1000);
});
p.then((value) => {
return new Promise((resolve, reject) => {
resolve("success");
});
})
.then((value) => {
console.log(value);
})
.then((value) => {
// 因为上一个then没有返回值,所以这里打印是undefinded
console.log(value);
});
</script>
</body>
</html>
6、7:
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>promise的几个关键问题</title>
</head>
<body>
<script>
/*
6.promise异常传透?
(1)当使用promise的then链式调用时, 可以在最后指定失败的回调,
(2)前面任何操作出了异常, 都会传到最后失败的回调中处理
7.中断promise链?
(1)当使用promise的then链式调用时, 在中间中断, 不再调用后面的回调函数
(2)办法: 在回调函数中返回一个pendding状态的promise对象
*/
let p = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("ok");
// reject("Error!");
}, 1000);
});
p.then((value) => {
console.log(111);
// throw "出错啦!";
// 中断promise链 有且只有一种方式
// return new Promise(() => {});
})
.then((value) => {
console.log(222);
})
.then((value) => {
console.log(333);
})
.catch((reason) => {
console.warn(reason);
});
</script>
</body>
</html>
自定义(手写)Promise
资料:
整体框架
js
/**
* 自定义Promise函数模块:IIFE
*/
(function (window) {
const PENDING = 'pending'
const RESOLVED = 'fulfilled'
const REJECTED = 'rejected'
/**
* Promise构造函数
* @param {function} executor 执行器函数(同步执行)(resolve, reject) => {}
*/
function Promise(executor) {
}
/**
* Promise原型对象then方法
* 指定成功和失败的回调函数
* @param {function} onResolved 成功的回调函数(value) => {}
* @param {function} onRejected 失败的回调函数(reason) => {}
* @returns 一个新的promise对象结果由onResolved/onRejected执行的结果决定
*/
Promise.prototype.then = function (onResolved, onRejected) {
}
/**
* Promise原型对象catch方法
* 指定失败的回调函数
* @param {function} onRejected 失败的回调函数(reason) => {}
* @returns 一个新的promise对象
*/
Promise.prototype.catch = function (onRejected) {
}
/**
* Promise函数对象resolve方法
* @param {*} value 成功的值
* @returns 一个成功/失败的promise
*/
Promise.resolve = function (value) {
}
/**
* Promise函数对象reject方法
* @param {*} resaon 失败的原因
* @returns 一个失败的promise
*/
Promise.reject = function (resaon) {
}
/**
* Promise函数对象all方法
* @param {Array<Promise>} promises
* @returns 一个promise,只有当所有promise都成功时才成功,否则只要有一个失败就失败
*/
Promise.all = function (promises) {
}
/**
*Promise函数对象race方法
* @param {Array<Promise>} promises
* @returns 返回 一个promise,其结果由第一个完成的promise决定
*/
Promise.race = function (promises) {
}
// 向外暴露Promise函数
window.Promise = Promise
})(window)
手写(有bug)
js
class Promise{
// 构造方法
constructor(executor){
// 声明构造函数
function Promise(executor){
// 保存实例对象的this值
const self = this;
// 添加属性并设置属性的初始值
self.PromiseState = 'pending';
self.PromiseResult = null;
// 声明属性 创建一个属性数组来存储多个异步的任务
self.callbacks = [];
// 这里的 self 常量名可以使用self、_this、that(潜规则),也可以使用其他
// resolve 函数
function resolve(data){
// 判断状态
if(self.PromiseState !== 'pending') return
// 修改状态(promiseState) 设置结果值(promiseResult)
self.PromiseState = 'fullfilled';
self.PromiseResult = data;
// 调用成功的回调函数(异步)
// 使用遍历将callbacks里面的所有属性调出来作为参数执行方法
if(self.callbacks.length > 0) {
setTimeout(() => {
self.callbacks.forEach(item => {
item.onResolved(data);
});
}, 0)
}
// if(self.callbacks.onResolved){
// self.callbacks.onResolved(data);
// }
};
// reject函数
function reject(data){
// 判断状态
if(self.PromiseState !== 'pending') return
// 修改状态(promiseState) 设置结果值(promiseResult)
self.PromiseState = 'rejected';
self.PromiseResult = data;
// 调用成功的回调函数(异步)
// 使用遍历将callbacks里面的所有属性调出来作为参数执行方法
// 如果有待执行的callback函数,立即【异步】执行回调函数onRejected
if(self.callbacks.length > 0) {
setTimeout(() => {
self.callbacks.forEach(item => {
item.onRejected(data);
})
}, 0);
}
// if(self.callbacks.onResolved){
// self.callbacks.onResolved(data);
// }
};
// 同步调用 执行器函数
try {
executor(resolve, reject);
} catch (e) {
// 修改 promise 对象状态为 失败
reject(e);
}
}
}
// then 方法封装 错误,无法实现!
then(onResolved,onRejected){
const self = this;
// 判断回调函数参数
if(typeof onRejected !== 'function'){
onRejected = reason => {
throw reason;
}
}
if(typeof onResolved !== 'function'){
onResolved = value => value;
// 这是简写形式,相当于:value => {return value};
}
return new Promise((resolve, reject) => {
// 封装函数
function callback(type){
try {
// 获取回调函数的执行结果
const result = type(self.PromiseResult);
// 判断 result 是否是 promise 类型的对象
if(result instanceof Promise){
result.then(v => {
resolve(v);
}, r => {
reject(r);
})
}else{
// 结果对象为【成功】
resolve(result);
};
} catch (e) {
reject(e);
}
}
// 调用回调函数
if(self.PromiseState === 'fulfilled'){
// 加定时器来实现异步
setTimeout(()=>{
callback(onResolved);
})
};
if(self.PromiseState === 'rejected'){
// 加定时器来实现异步
setTimeout(()=>{
callback(onRejected);
});
};
// 判断pending状态
if(self.PromiseState === 'pending'){
// 保存回调函数
self.callbacks.push({
// onResolved: onResolved,
// onRejected: onRejected
onResolved: function(){
callback(onResolved);
},
onRejected: function(){
callback(onRejected);
},
});
};
})
}
// catch 方法
catch(onRejected){
return this.then(undefined, onRejected);
}
//resolve方法
static resolve(value){
// 返回promise对象
return new Promise((resolve, reject) => {
if(value instanceof Promise){
value.then(v=>{
resolve(v);
}, r=>{
reject(r);
})
}else{
// 状态设置为成功
resolve(value);
}
})
}
// 添加 reject 方法
static reject(reason){
return new Promise((resolve, reject)=>{
reject(reason);
})
}
// 添加all方法
static all(promises){
// 声明变量
let count = 0;
let arr = [];
// 返回结果为promise对象
return new Promise((resolve,reject) => {
// 遍历
for (let i = 0; i < promises.length; i++) {
promises[i].then(v => {
// 得知对象的状态是成功 每个promise对象都成功
count++;
// 将当前promise对象成功的结果存入数组
arr[i] = v;
// 判断
if(count === promises.length){
// 修改状态
resolve(arr);
}
},r => {
reject(r);
});
}
})
}
// 添加race方法
static race(promises){
return new Promise((resolve, reject)=> {
for (let i = 0; i < promises.length; i++) {
promises[i].then(v => {
// 修改对象的状态为成功
resolve(v);
},r=>{
// 修改对象的状态为失败
reject(r);
});
}
})
}
}
async
- 函数的返回值为 promise 对象
- promise 对象的结果由 async 函数执行的返回值决定
js
// 和then类似
async function main() {
// 1.如果返回值是一个非promise类型的数据,状态为成功,结果值就是return的值
// return 521;
// 2.如果返回是一个promise类型的数据,状态由对象的状态决定,结果值是函数里参数
// return new Promise((resolve, reject) => {
// // resolve("ok");
// reject(error)
// });
// 3.抛出异常 状态为失败,结果为抛出异常的值
throw "oh!!!";
}
let result = main();
console.log(result);
await
- await 右侧的表达式一般为 promise 对象, 但也可以是其它的值
- 如果表达式是 promise 对象, await 返回的是 promise 成功的值
- 如果表达式是其它值, 直接将此值作为 await 的返回值
注意
- await 必须写在 async 函数中, 但 async 函数中可以没有 await
- 如果 await 的 promise 失败了, 就会抛出异常, 需要通过 try...catch 捕获处理
js
async function main() {
let p = new Promise((resolve, reject) => {
// resolve("ok");
reject("error");
});
// 1.右侧为promise的情况
// let res = await p;
// 2.右侧为其它类型的数据
let res2 = await 20;
// 3.1情况将resolve改为reject情况
try {
let res3 = await p;
} catch (e) {
console.log(e);
}
console.log(res);
console.log(res2);
}
main();
async和await结合实践
js
/**
* 读取,resource目录下的1.html,2.html,3.html文件的内容
*/
const fs = require('fs');
const util = require('util');
// util的一个方法,将api转换为promise对象
const mineReadFile = util.promisify(fs.readFile);
// 回调函数的方式
// fs.readFile('./resource/1.html', (err, data1) => {
// if(err) throw err;
// fs.readFile('./resource/2.html', (err, data2) => {
// if(err) throw err;
// fs.readFile('./resource/3.html', (err, data3) => {
// if(err) throw err;
// });
// });
// });
// async await 方式
async function main(){
try {
// 读取文件的内容
let data1 = await mineReadFile('./resource/1.html');
let data2 = await mineReadFile('./resource/2.html');
let data3 = await mineReadFile('./resource/3.html');
console.log(data1 + data2 + data3);
} catch (e) {
console.log(e);
}
}
main();
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>11_async与await</title>
</head>
<body>
<button id="btn">点击获取段子</button>
<script>
// axios
function sendAJAX(url) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.responseType = "json";
xhr.open("GET", url);
xhr.send();
// 处理结果
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
// 状态码判断
if (xhr.status >= 200 && xhr.status < 300) {
// 成功的结果
resolve(xhr.response);
} else {
// 失败的结果
reject(xhr.status);
}
}
};
});
}
let btn = document.querySelector("#btn");
btn.addEventListener("click", async function () {
// 获取段子信息
let duanzi = await await sendAJAX("https://api.apiopen.top/getJoke");
console.log(duanzi);
});
</script>
</body>
</html>