异步编程大法:Promsise

在现代JavaScript开发中,异步编程是不可避免的。无论是网络请求、文件读写,还是定时任务,都需要处理异步操作。Promise 是 JavaScript 中处理异步操作的核心工具之一。

1. 什么是Promise?

Promise 是 JavaScript 中用于表示异步操作的对象。它代表一个异步操作的最终完成(或失败)及其结果值。Promise 有三种状态:

  1. Pending(进行中):初始状态,表示异步操作尚未完成。
  2. Fulfilled(已成功):表示异步操作成功完成。
  3. Rejected(已失败):表示异步操作失败。

Promise 的状态一旦改变,就不会再变。例如,从 Pending 变为 Fulfilled 后,就不会再变为 Rejected。


2. 创建一个Promise

Promise 的构造函数接受一个函数作为参数,这个函数被称为 执行器(executor)。执行器函数有两个参数:

  • resolve:用于将 Promise 的状态从 Pending 变为 Fulfilled,并传递结果值。
  • reject:用于将 Promise 的状态从 Pending 变为 Rejected,并传递错误信息。
1
2
3
4
5
6
7
8
9
10
11
12
13
const myPromise = new Promise((resolve, reject) => {
// 模拟异步操作
// 注意事项:不能在异步中去执行throw error的操作,后续catch捕获不到
setTimeout(() => {
const success = true; // 假设操作成功
if (success) {
resolve('操作成功!');
} else {
reject('操作失败!');
}
}, 1000);
});


3. 使用Promise

3.1 then 方法

then 方法用于处理 Promise 的成功状态。它接受两个回调函数作为参数:

  • 第一个回调函数:处理 Fulfilled 状态,接收 resolve 传递的值。
  • 第二个回调函数(可选):处理 Rejected 状态,接收 reject 传递的错误信息。
1
2
3
4
5
6
7
8
myPromise.then(
(result) => {
console.log(result); // 输出: 操作成功!
},
(error) => {
console.error(error); // 输出: 操作失败!
}
);

3.2 catch 方法

catch 方法用于处理 Promise 的失败状态。它相当于 then(null, errorCallback)

1
2
3
4
5
6
7
myPromise
.then((result) => {
console.log(result); // 输出: 操作成功!
})
.catch((error) => {
console.error(error); // 输出: 操作失败!
});

3.3 finally 方法

finally 方法用于在 Promise 完成后(无论成功或失败)执行某些操作。它不接受任何参数。

1
2
3
4
5
6
7
8
9
10
myPromise
.then((result) => {
console.log(result); // 输出: 操作成功!
})
.catch((error) => {
console.error(error); // 输出: 操作失败!
})
.finally(() => {
console.log('操作完成!'); // 输出: 操作完成!
});

4. Promise链式调用

Promise 支持链式调用,即在一个 then 方法中返回一个新的 Promise,从而可以继续调用 then 方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
const fetchData = () => {
return new Promise((resolve) => {
setTimeout(() => {
resolve('数据加载完成!');
}, 1000);
});
};

fetchData()
.then((result) => {
console.log(result); // 输出: 数据加载完成!
return '处理数据...';
})
.then((result) => {
console.log(result); // 输出: 处理数据...
return new Promise((resolve) => {
setTimeout(() => {
resolve('数据处理完成!');
}, 1000);
});
})
.then((result) => {
console.log(result); // 输出: 数据处理完成!
});

5. Promise的静态方法

5.1 Promise.resolve

Promise.resolve 用于创建一个立即成功的 Promise。

1
2
3
Promise.resolve('立即成功').then((result) => {
console.log(result); // 输出: 立即成功
});

5.2 Promise.reject

Promise.reject 用于创建一个立即失败的 Promise。

1
2
3
Promise.reject('立即失败').catch((error) => {
console.error(error); // 输出: 立即失败
});

5.3 Promise.all

Promise.all 用于并行执行多个 Promise,并在所有 Promise 都成功时返回结果数组。如果其中一个 Promise 失败,则立即返回失败。

1
2
3
4
5
6
7
8
9
10
11
const promise1 = Promise.resolve('结果1');
const promise2 = Promise.resolve('结果2');
const promise3 = new Promise((resolve) => setTimeout(resolve, 1000, '结果3'));

Promise.all([promise1, promise2, promise3])
.then((results) => {
console.log(results); // 输出: ['结果1', '结果2', '结果3']
})
.catch((error) => {
console.error(error);
});

5.4 Promise.race

Promise.race 用于并行执行多个 Promise,并返回最先完成的 Promise 的结果(无论成功或失败)。

1
2
3
4
5
6
7
8
9
10
const promise1 = new Promise((resolve) => setTimeout(resolve, 500, '结果1'));
const promise2 = new Promise((resolve) => setTimeout(resolve, 1000, '结果2'));

Promise.race([promise1, promise2])
.then((result) => {
console.log(result); // 输出: 结果1
})
.catch((error) => {
console.error(error);
});