5.03 Promise机制

[!TIP] Promise 我原以为 Promise 是一个对象,或者是函数,没想到应该算是异步处理过程中的一种机制,或者处理的方式、流程吧。

在网络请求过程中,经常见到。异步,我过去理解得有偏差,异步是让当前的花费较大时间的流程走了“另外一条道”,主要道路是留给原来的程序走,不会耽误主程序的正常运行。

我所理解的异步,是这样的:在主程序的行程中,遇到了浪费时间的子程序,那么我就让这个子程序走向“另外一条道路”,而主程序的流程是继续的,等着“费时”的子程序(也就是所谓的异步过程)完成后,就会把结果反馈给主程序。我这样理解对么?还有什么需要补充的?

这里 sonnet 的相关回答,我觉得还是很有参考意义的。 [[5.04 异步编程的核心概念]]

2024-07-12 17:11:56

  1. Promise 基本概念:

Promise 代表一个异步操作的最终完成(或失败)及其结果值。它有三种状态: - Pending(进行中) - Fulfilled(已成功) - Rejected(已失败)

  1. Promise 的类型定义:
interface Promise<T> {
  then<TResult1 = T, TResult2 = never>(
    onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | undefined | null,
    onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null
  ): Promise<TResult1 | TResult2>;
  catch<TResult = never>(
    onrejected?: ((reason: any) => TResult | PromiseLike<TResult>) | undefined | null
  ): Promise<T | TResult>;
  finally(onfinally?: (() => void) | undefined | null): Promise<T>;
}
  1. 创建 Promise:
const myPromise: Promise<string> = new Promise((resolve, reject) => {
  setTimeout(() => {
    if (Math.random() > 0.5) {
      resolve("Success!");
    } else {
      reject("Error!");
    }
  }, 1000);
});
  1. 使用 Promise:
myPromise
  .then((result: string) => {
    console.log(result);  // "Success!"
  })
  .catch((error: string) => {
    console.error(error);  // "Error!"
  })
  .finally(() => {
    console.log("Promise completed");
  });
  1. Promise 链:
function fetchUser(): Promise<User> {
  return fetch('/api/user')
    .then(response => response.json())
    .then(data => new User(data));
}

fetchUser()
  .then(user => user.getPosts())
  .then(posts => console.log(posts))
  .catch(error => console.error(error));
  1. Promise. All:
const promises: Promise<number>[] = [
  Promise.resolve(1),
  Promise.resolve(2),
  Promise.resolve(3)
];

Promise.all(promises)
  .then((results: number[]) => {
    console.log(results);  // [1, 2, 3]
  });
  1. Promise. Race:
const promise1 = new Promise(resolve => setTimeout(() => resolve('one'), 500));
const promise2 = new Promise(resolve => setTimeout(() => resolve('two'), 100));

Promise.race([promise1, promise2])
  .then((value: string) => {
    console.log(value);  // "two"
  });
  1. Async/await 语法:
async function fetchData(): Promise<Data> {
  try {
    const response = await fetch('https://api.example.com/data');
    const data: Data = await response.json();
    return data;
  } catch (error) {
    console.error('Error fetching data:', error);
    throw error;
  }
}
  1. 泛型 Promise:
function delay<T>(ms: number, value: T): Promise<T> {
  return new Promise(resolve => setTimeout(() => resolve(value), ms));
}

delay<string>(1000, "Hello").then(str => console.log(str));
  1. Promise 错误处理:

    function fetchData(): Promise<Data> {
      return fetch('https://api.example.com/data')
        .then(response => {
          if (!response.ok) {
            throw new Error(`HTTP error! status: ${response.status}`);
          }
          return response.json();
        });
    }
    
    fetchData()
      .then(data => console.log(data))
      .catch(error => {
        if (error instanceof Error) {
          console.error('An error occurred:', error.message);
        } else {
          console.error('An unknown error occurred');
        }
      });
    
  2. 转换回调为 Promise:

    function readFilePromise(path: string): Promise<string> {
      return new Promise((resolve, reject) => {
        fs.readFile(path, 'utf8', (err, data) => {
          if (err) reject(err);
          else resolve(data);
        });
      });
    }
    
  3. 并发控制:

    async function fetchAllData(urls: string[]): Promise<any[]> {
      const concurrencyLimit = 3;
      const results: any[] = [];
    
      for (let i = 0; i < urls.length; i += concurrencyLimit) {
        const batch = urls.slice(i, i + concurrencyLimit);
        const batchResults = await Promise.all(batch.map(url => fetch(url).then(res => res.json())));
        results.push(...batchResults);
      }
    
      return results;
    }
    

TypeScript 中的 Promise 提供了强大的类型检查和智能提示,使得处理异步操作更加安全和高效。通过正确使用 Promise,你可以编写更清晰、更易于维护的异步代码,同时避免回调地狱的问题。结合 async/await 语法,可以使异步代码的编写和阅读变得更加直观和线性化。