用来解决回调地狱。回调地狱也就是回调函数中嵌套了回调函数,代码阅读性低。
例如如下代码:
const fs = require("fs");
// 读A文件
fs.readFile(`${__dirname}/etc/a.txt`, "utf-8", (err, data) => {
if (err) {
console.log(err);
} else {
console.log(data);
// 读B文件
fs.readFile(`${__dirname}/etc/b.txt`, "utf-8", (err, data) => {
if (err) {
console.log(err);
} else {
console.log(data);
// 读C文件
fs.readFile(`${__dirname}/etc/c.txt`, "utf-8", (err, data) => {
if (err) {
console.log(err);
} else {
console.log(data);
}
});
}
});
}
});
在读完A文件后读取B文件在读取C文件。
Promise
对象是一个构造函数,用来生成Promise
实例。Promise
构造函数接收一个函数作为参数。这个参数的函数又有两个参数,这两个参数分别是resolve
和reject
。这两个参数也是函数,由JavaScript引擎提供。
resolve()
方法,他内部调用了then()
里面的第一个参数函数。reject()
方法,他内部调用了then()
里面的第二个参数函数。const fs = require("fs");
let p = new Promise((resolve, reject) => {
// 读文件
fs.readFile(`${__dirname}/etc/a.txt`, "utf-8", (err, data) => {
if (!err) {
// 读取成功
resolve(data); // 调用此方法
} else {
// 读取失败
reject(err); // 调用此方法
}
});
});
p.then(
(data) => {
console.log(data);
},
(err) => {
console.log(err);
}
);
Promise
对象代表一个异步操作,有三种状态:pending
(进行中)、fulfilled
(已成功)和rejected
(已失败)。
只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。
Promise
对象的状态改变,只有两种可能:
pending
变为fulfilled
pending
变为rejected
Promise
对象后立即执行。
const fs = require("fs"); let p = new Promise((resolve, reject) => { console.log("promise - test"); // 读文件 fs.readFile(`${__dirname}/etc/a.txt`, "utf-8", (err, data) => { if (!err) { // 读取成功 resolve(data); // 调用此方法 } else { // 读取失败 reject(err); // 调用此方法 } }); }); p.then( (data) => { console.log(data); }, (err) => { console.log(err); } ); console.log("promise end- test");因此不要在Promise里面写其他的代码,只写异步操作即可。
让异步操作的本质实际上就是在异步操作成功后的回调函数里返回另外的Promise
,在执行另一个then
方法。
const fs = require("fs");
function getPromise(fileName) {
return new Promise((resolve, reject) => {
// 读文件
fs.readFile(`${__dirname}/etc/${fileName}.txt`, "utf-8", (err, data) => {
if (!err) {
// 读取成功
resolve(data); // 调用此方法
} else {
// 读取失败
reject(err); // 调用此方法
}
});
});
}
getPromise("a")
.then((data) => {
console.log(data);
return getPromise("b");
})
.then((data) => {
console.log(data);
return getPromise("c");
})
.then((data) => {
console.log(data);
});
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/jquery@latest/dist/jquery.min.js"></script>
</head>
<body>
<button id="btn">点我看笑话</button>
<script>
$('#btn').on('click', function () {
$.ajax({
type: 'get',
url: 'https://v1.hitokoto.cn/?a=g&encode=json',
}).then((backData) => {
console.log(backData.hitokoto);
}, (err) => {
console.log(err);
})
})
</script>
</body>
</html>
此方法能够抓取错误,在最后一个then()
方法后边在加一个catch
方法。无论哪一个出错都会抓取到错误。
getPromise("a")
.then((data) => {
console.log(data);
return getPromise("b");
})
.then((data) => {
console.log(data);
return getPromise("c1");
})
.then((data) => {
console.log(data);
})
.catch((err) => {
console.log(err);
});
Promise.all()
方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。
let p1 = getPromise("a");
let p2 = getPromise("b");
let p3 = getPromise("c");
let pAll = Promise.all([p1, p2, p3]);
pAll.then((data) => {
console.log(data);
});
此方法要求每一个小的
Promise
都要成功,只要有一个失败都会导致整个的Promise
错误。
Promise.race()
方法同样是将多个 Promise 实例,包装成一个新的 Promise 实例。
此方法与all
方法的区别是只要有一个成功即成功。
let p1 = getPromise("a");
let p2 = getPromise("b");
let p3 = getPromise("c");
let pRace = Promise.race([p1, p2, p3]);
pRace.then((data) => {
console.log(data);
});
使用模块的好处
export
命令:用于规定模块对外的接口import
命令:用于输入其他模块提供的功能注意:module是静态导入,因此不能使用表达式和变量那些运行时才能知道的结果的变量。
通过export
导出
通过inport
导入
导入的变量只能读不能修改。
HTML
引入模块
在HTML引入
<script type="module" src="./10-import.js"></script>
浏览器加载 ES6 模块,也使用<script>
标签,但是要加入type="module"
属性。
{}
。默认输出,导入时不要加{}
一个模块中只能由一个export default
export default function () { console.log("temp"); }import myfn from "./export.js";在上面的三个文件中,import.js
需要使用export.hs
中的变量,而export.js
又需要使用public.js
中的变量。此时可以使用复合写法。
public.js
export let number1 = 10;
export.js
// 导入public.js的number1变量
// 继续导出给 import.js 使用
// 复合写法
export { number1 } from "./public.js";
import.js
import { number1 } from "./export.js";
console.log(number1);