今天我们来讲一下 js 里面的重要函数 promise
Promise
承诺多少个状态
持续 pending
成功 resolved
失败 rejected
ES6 的语法
专门用来解决回调地域问题
Promise 的语法
Promise 是 ES6 内置的构造函数
使用方法: new Promise(function () { 你要执行的异步的事情 })
实例化的时候, 这个函数接收两个参数
resolve, reject
使用方法:
实例化对象身上由两个方法
1. then()
promise 对象.then(function () {})
初始化 Promise 时,执行器函数改变了 Promise 的状态。执行器函数同步执行。异步操作返回的数据(成功的值和失败的原因)可以交给.then 处理,为 Promise 实例提供处理程序。
Promise 实例生成以后,可以用 then 方法分别指定 resolved 状态和 rejected 状态的回调函数。这两个函数 onFulfilled,onRejected 都是可选的,不一定要提供。如果提供,则会 Promise 分别进入 resolved 状态和 rejected 状态时执行。
而且任何传给 then 方法的非函数类型参数都会被静默忽略
then 方法必须返回一个新的 promise 对象
2. catch()
promise 对象.catch(function () {})
then 方法的函数传递给了 实例化的 resolve
catch 方法的函数传递给了 实例化的 reject
当第一个.then 的异常被捕获后可以继续执行。
//1. promise 基础语法
const p = new Promise(function (resolve, reject) {
// resolve 是成功的回调函数
// 当你书写 resolve() 的时候, 实际上是在调用 then 里面的函数
// reject 是失败的回调函数
// 当你书写 reject() 的时候, 实际上是在调用 catch 里面的函数
ajax({
url: './server/a1.php',
dataType: 'json',
success (res) {
resolve(res)
},
error (err) {
reject(err)
}
})
})
调用 then 方法
调用 catch 方法
p.then(function (res) {
console.log('我执行了', res)
})
p.catch(function (err) {
console.log('我失败了', err)
// })
复制代码
3. Promise 的另一种语法
Promise.all()
目的是把多个 promise 对象封装成一个
使用方法: Promise.all([ promise 对象 1, promise 对象 2, ... ]).then(function () {})
then 里面会接收所有 promise 完成以后的结果, 以一个数组的形式给你返回
致命缺点: 必须三个全部成功, 由任何一个失败, 那么最终你一个结果也得不到
//原生primose all();
const p1 = Promise.resolve('p1')
const p2 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('p2 延时一秒')
}, 1000)
})
const p3 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('p3 延时两秒')
}, 2000)
})
const p4 = Promise.reject('p4 rejected')
const p5 = new Promise((resolve, reject) => {
setTimeout(() => {
reject('p5 rejected 延时1.5秒')
}, 1500)
})
// 所有Promise实例都成功
Promise.all([p1, p2, p3])
.then(res => {
console.log(res)
})
.catch(err => console.log(err)) // 2秒后打印 [ 'p1', 'p2 延时一秒', 'p3 延时两秒' ]
// 一个Promise实例失败
Promise.all([p1, p2, p4])
.then(res => {
console.log(res)
})
.catch(err => console.log(err)) // p4 rejected
// 一个延时失败的Promise
Promise.all([p1, p2, p5])
.then(res => {
console.log(res)
})
.catch(err => console.log(err)) // 1.5秒后打印 p5 rejected
// 两个Promise实例失败
Promise.all([p1, p4, p5])
.then(res => {
console.log(res)
})
.catch(err => console.log(err)) // p4 rejected
复制代码
上述实例得到,all 的性质:
所有都成功,则合成 Promise 的返回值就是所有子 Promise 的返回值数组。
有一个失败,那么第一个失败的会把自己的理由作为合成 Promise 的失败理由。
Promise 的进阶语法
当你在 promise 对象的 then 里面返回一个新的 promise 对象
可以在这个 then 的后面继续来一个 then 接收第一个 then 里面 promise 对象的结果
改变封装异步代码的思路
按照 promise 的思想来封装异步代码
分析: 为什么可以使用 then
得是一个 promise 对象
封装:
function pAjax() {}
只要 pAjax 里面返回的是一个 promise 对象
pAjax({ 配置项 }).then()
//2. Promise 进阶语法
new Promise(function (resolve, reject) {
ajax({
url: './a.php',
dataType: 'json',
success (res) {
resolve(res)
}
})
})
.then(function (res) {
console.log('需求1: ', res)
return new Promise(function (resolve, reject) {
ajax({
url: './b.php',
data: res,
dataType: 'json',
success (res) {
resolve(res)
}
})
})
})
.then(function (res) {
console.log('需求2: ', res)
return new Promise(function (resolve, reject) {
ajax({
url: './c.php',
data: res,
dataType: 'json',
success (res) {
resolve(res)
}
})
})
})
.then(function (res) {
console.log('需求3: ', res)
})
复制代码
a.php
<?php
$arr = array(
"a" => 10,
"b" => 20
);
echo json_encode($arr);
?>
复制代码
b.php
<?php
$a = $_GET['a'];
$b = $_GET['b'];
$arr = array(
"c" => $a + $b,
"d" => 5
);
echo json_encode($arr);
?>
复制代码
c.php
<?php
$c = $_GET['c'];
$d = $_GET['d'];
$arr = array(
"e" => $c * $d,
"message" => "到此为止"
);
echo json_encode($arr);
?>
复制代码
结语
promise 作为前端中比较常用的构造函数之一 ,希望本篇文章能够帮助大家更好的理解 promise。
评论