# TypeScript Promise
Promise 是 异步编程的新解决方案。语法上 Promise 是一个构造函数, 用来封装异步操作并可以获取其成功或失败的结果。
- Promise 构造函数: Promise (excutor) {}
- Promise.prototype.then 方法
- Promise.prototype.catch 方法
Promise.prototype.then
then 方法的返回结果也是一个 Promise 对象(所以 then 方法可以链式调用),这个对象的状态由回调函数的执行结果来决定
- 回调函数中返回的结果是非 Promise 类型数据,那么状态为成功,返回值为对象的成功的值
- 回调函数中返回的结果是一个 Promise 类型数据,那么状态由结果中的 Promise 状态来决定
- 抛出错误,那么状态为失败,错误的值为抛出来的值
// 返回值是 Promise
// 运行成功用 resolve
// 运行失败用 reject
function add(a: number, b: number): Promise<number> {
return new Promise((resolve, reject) => {
if( b % 17 === 0){
reject('bad number: ' + b)
}
setTimeout(() => {
resolve(a + b)
}, 2000)
})
}
const res1 = add(1, 3)
// then 中第一个参数是捕获 resolve 的
// then 中第二个参数是捕获 reject 的
res1.then((value) => {
console.log('计算结果:' + value)
// 串联,用 Promise 不会有回调地狱
return add(value, 17)
}, (reason) => {
console.log('计算失败,原因是 ' + reason)
}).catch((reason) => {
console.log('计算失败,原因是 ' + reason)
})
Promise.all([p1, p2,...])
- all() 只要遇到一个 reject 就会停止;
- all() 返回的是成功的 Promise 的结果的数组;
- all() 中的 Promise 的并行运行的;
function add(a: number, b: number): Promise<number> {
return new Promise((resolve, reject) => {
if( b % 17 === 0){
reject('bad number: ' + b)
}
setTimeout(() => {
resolve(a + b)
}, 2000)
})
}
Promise.all([add(2, 3), add(4, 5)]).then(value =>{
// 等待两个加法都完成了
const [a,b] = value
console.log('result:', a, b)
// 再对两个结果进行相加
return add(a, b)
}).then(value => {
console.log('final result: ' + value)
})
Promise.race([p1, p2,...] ):
- 比赛,看谁运行得快就返回谁
function add(a: number, b: number): Promise<number> {
return new Promise((resolve, reject) => {
if( b % 17 === 0){
reject('bad number: ' + b)
}
setTimeout(() => {
resolve(a + b)
}, 2000)
})
}
Promise.race([add(2, 3), add(4, 5)]).then(value =>{
console.log('result: ' + value)
})
async 和 await
async 和 await 两种语法结合可以让异步代码像同步代码一样。
async 函数的返回值为 Promise 对象,Promise 对象的结果由 async 函数执行的返回值决定:
- 返回非 Promise 类型的对象,结果都是成功的 Promise 对象
- 返回成功的 Promise 对象,结果就是这个成功的 Promise 对象
- 返回失败的 Promise 对象,结果就是这个失败的 Promise 对象
- 抛出异常,结果就是失败的 Promise 对象
await 表达式:
- await 必须写在 async 函数中
- await 右侧的表达式一般为 Promise 对象
- await 返回的是 Promise 成功的值
- await 的 Promise 失败了, 就会抛出异常, 需要通过 try...catch 捕获处理
// 发送 Ajax 请求,返回结果是 Promise 对象
function sendAjax(url: string) {
return new Promise((resolve, reject) => {
//1. 创建对象
const x = new XMLHttpRequest();
//2. 初始化
x.open("GET", url);
//3. 发送请求
x.send();
//4. 绑定事件
x.onreadystatechange = function() {
//到4表示所有响应已经回来了
if(x.readyState === 4) {
if(x.status >= 200 && x.status < 300) {
resolve(x.response);
}
reject(x.status);
}
}
})
}
let jokeUrl = "https://api.apiopen.top/getJoke";
async function main(){
try {
let result = await sendAjax(jokeUrl);
console.log(result);
}catch (e) {
console.error(e);
}
}
main();