promise
异步函数 与 回调函数的说明
异步函数: 定时器setTimeout, ajax (异步函数的执行, 不会阻塞主线程代码的执行)
回调函数:
-
把一个函数当成参数传递, 将来特定的时机调用, 这个函数就叫回调函数
-
什么时候会用到回调函数, 异步的时候 ajax success error
console.log(1) setTimeout(function() { console.log(2) setTimeout(function() { console.log(4) }, 1000) console.log(5) }, 1000) console.log(3) 答案是:1 3 2 5 4
回调函数的问题:
- 回调函数的阅读性不好, 回调不会立马执行
- 回调函数如果有大量的嵌套, 可维护性差 (回调地狱)
promise 就是为了解决回调函数嵌套的问题而存在的
回调函数的嵌套问题
文件读写, 也是异步的
按照顺序依次读取 - a, b, c, d 四个文件
回调地狱: 回调函数嵌套回调函数, 嵌套多了, 将来就很难维护, 很难理清顺序
promise 的基本语法
promise:
1. 创建promise对象
resolve 是成功的时候, 需要调用的函数
reject 是失败的时候, 需要调用的函数
const p = new Promise(function(resolve,
reject) {
// 里面一般封装的是异步函数的处理
})
2. 使用promise对象
p.then(成功的函数).catch(失败的函数)
代码演示:
// 1. 创建promise对象
// 2. 使用promise对象
const fs = require('fs')
// promise承诺, 一般承诺的是将来的事情, 可能成功 也可能失败
// 1. 创建
const p = new Promise(function(resolve, reject) {
// promise中一般封装一个异步的操作 比如: ajax, 读写文件
// resolve 和 reject 都是 promise 给你提供好的函数
// resolve是需要在成功的时候调用的函数
// reject是需要在失败的时候调用的函数
fs.readFile('a.txt', 'utf8', (err, data) => {
if (err) {
reject(err)
} else {
resolve(data)
}
})
})
// 2. 使用promise对象
// axios({ .. }).then(成功的函数).catch(失败的函数)
// p.then(成功的函数).catch(失败的函数)
p.then(function(data) {
console.log(data)
}).catch(function(err) {
console.log(err)
})
目的: promise 是书写异步代码的另一种方式, 解决回调函数嵌套的问题
-
如何创建一个 promise 对象
const p = new Promise((resolve, reject) => { promise内部一般可以封装一个异步操作 成功调用 resolve 失败调用 reject })
-
如何使用一个 promise 对象
2. 使用 promise 对象 .then(res => { ... }) 处理成功 .catch(res => { ... }) 处理失败
promise有三种状态
-
pending: 等待 (进行中)
-
fulfilled: 成功 (已完成), 调用了 resolve, promise的状态就会被标记成成功
-
rejected: 失败 (拒绝), 调用了 reject, promise的状态就会被标记成失败
小tips: 一旦promise的状态发生变化, 状态就会被凝固
代码演示:
const fs = require('fs')
// promise对象, 是有三个状态的
// pending 等待(进行中) 默认的状态
// fulfilled 成功
// rejected 失败(被拒绝)
// 1. resolve是成功的时候需要执行的函数, 会将promise的状态修改成fulfilled
// 将来才会执行 .then 中配置的函数
// 2. reject是失败的时候需要执行的函数, 会将promise的状态修改成rejected
// 将来才会执行 .catch 中配置的函数
// 3. promise的状态只能修改一次, 一旦被修改了, 就会状态凝固 (应付面试题)
// 所以多次调用 resolve 或者 reject 是没有任何意义的
const p = new Promise(function(resolve, reject) {
fs.readFile('a.txt', 'utf8', (err, data) => {
if (err) {
reject(err) // rejected
// resolve(err) // 无意义的代码
} else {
resolve(data)
}
})
})
p.then(function(data) {
console.log(data)
}).catch(function(err) {
console.log(err)
})
promise 解决回调地狱的问题
如果有多个 promise 需要处理, 支持链式编程
const p = new Promise(function (resolve, reject) {
// promise 内部会封装一个异步的操作
// resolve: 成功的时候, 需要调用
// reject: 失败的时候, 需要调用
fs.readFile('a.txt', 'utf8', (err, data)