# TypeScript Promise

Promise 是 异步编程的新解决方案。语法上 Promise 是一个构造函数, 用来封装异步操作并可以获取其成功或失败的结果。

  1. Promise 构造函数: Promise (excutor) {}
  2. Promise.prototype.then 方法
  3. Promise.prototype.catch 方法

Promise.prototype.then

then 方法的返回结果也是一个 Promise 对象(所以 then 方法可以链式调用),这个对象的状态由回调函数的执行结果来决定

  1. 回调函数中返回的结果是非 Promise 类型数据,那么状态为成功,返回值为对象的成功的值
  2. 回调函数中返回的结果是一个 Promise 类型数据,那么状态由结果中的 Promise 状态来决定
  3. 抛出错误,那么状态为失败,错误的值为抛出来的值
// 返回值是 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 函数执行的返回值决定:

  1. 返回非 Promise 类型的对象,结果都是成功的 Promise 对象
  2. 返回成功的 Promise 对象,结果就是这个成功的 Promise 对象
  3. 返回失败的 Promise 对象,结果就是这个失败的 Promise 对象
  4. 抛出异常,结果就是失败的 Promise 对象

await 表达式:

  1. await 必须写在 async 函数中
  2. await 右侧的表达式一般为 Promise 对象
  3. await 返回的是 Promise 成功的值
  4. 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();
上次更新: 11/5/2021, 11:32:42 AM