2024/03/08 异步处理,解剖Promise

异步处理

异步处理是指在程序执行过程中,某些操作不会阻塞当前线程,而是通过回调函数、Promise、async/await 等方式来实现并发执行或延迟执行。异步处理通常用于处理耗时的操作,如网络请求、文件读写、定时器等,以避免阻塞主线程,提高程序的性能和响应速度。
复制代码

const fetchRequest = () => {
  return new Promise((resolve, reject) => {
    // 发送请求, 在回调中处理结果
    setTimeout(() =>{
      resolve('接口返回成功')
    }, 1000);
  })
}
fetchRequest().then((res) => {
  console.log(res);
})


// 使用 Promise 发起一个异步的网络请求
const fetchRequest = () => {
  return new Promise((resolve, reject) => {
    // 发送请求/定时器, 在回调中处理结果
    setTimeout(() =>{
      resolve('接口返回成功')
    }, 1000);
  })
}
fetchRequest().then((res) => {
  console.log(res);
})

// 文件读写
// Node.js 提供了 fs 模块来处理文件的读写操作。要读取一个文本文件的内容,可以使用 fs.readFile 方法,具体示例如下:
const fs = require('fs');
// 读取文件
fs.readFile('file.txt', 'utf8', (err, data) => {
  if (err) {
    console.error(err);
    return;
  }
  console.log(data);
});

// Promise 的异步链式调用
const asyncTask1 = () => {
  return new Promise((resolve, reject) => {
    // 发送请求/定时器, 在回调中处理结果
    setTimeout(() =>{
      resolve('第一个任务执行完成')
    }, 1000);
  })
}

const asyncTask2 = () => {
  return new Promise((resolve, reject) => {
    // 发送请求/定时器, 在回调中处理结果
    setTimeout(() =>{
      resolve('第二个任务执行完成')
    }, 1000);
  })
}

asyncTask1().then((res) => {
  console.log(res);
  return asyncTask2()
}).then((res) => {
  console.log(res);
})
复制代码

Promise 的源码解析可以帮助我们更深入地理解其内部实现原理。

以下是一个简化的 Promise 源码实现,用于说明 Promise 的基本工作原理
复制代码
// Promise 构造函数
function PromiseDemo(executor) {
  this.status = 'pending'; // 初始状态为 pending
  this.value = undefined;   // 成功时的返回值
  this.reason = undefined;  // 失败时的原因
  this.onResolvedCallbacks = []; // 存储成功时的回调
  this.onRejectedCallbacks = [];  // 存储失败时的回调

  const resolve = value => {
    if (this.status === 'pending') {
      this.status = 'fulfilled';
      this.value = value;
      // 微任务:将成功态的回调放入微任务队列中
      this.onResolvedCallbacks.forEach(function (fn) { return this.value = fn(); });
    }
  };

  const reject = reason => {
    if (this.status === 'pending') {
      this.status = 'rejected';
      this.reason = reason;
      this.onRejectedCallbacks.forEach(function (fn) { return this.value = fn(); });
    }
  };

  // 执行传入的 executor 函数,并传入 resolve 和 reject 作为参数
  try {
    executor(resolve, reject);
  } catch (e) {
    reject(e);
  }
}

// then 方法
PromiseDemo.prototype.then = function (onFulfilled, onRejected) {
  const promise2 = new PromiseDemo((resolve, reject) => {
    if (this.status == "fulfilled") {
      console.log('1111111111')
      try {
        const x = onFulfilled(this.value)
        resolve(x)
      } catch (error) {
        reject(error)
      }
    }
    if (this.status == "rejected") {
      console.log('22222222222')
      try {
        const x = onRejected(this.reason)
        resolve(x)
      } catch (error) {
        reject(error)
      }
    }
    if (this.status == "pending") {
      console.log('3333333333333')
      this.onResolvedCallbacks.push(() => {
        if (this.status == "fulfilled") {
          try {
            const x = onFulfilled(this.value)
            resolve(x)
          } catch (error) {
            reject(error)
          }
        }
      })
      this.onRejectedCallbacks.push(() => {
        if (this.status == "rejected") {
          try {
            const x = onRejected(this.reason)
            resolve(x)
          } catch (error) {
            reject(error)
          }
        }
      })
    } else {
      console.log('444444444444')
      // 执行完所有回调函数之后,清空回调数组
      this.onResolvedCallbacks = [];
      this.onRejectedCallbacks = [];
    }
  })
  return promise2;
}

PromiseDemo.prototype.catch = function (onRejected) {
  return this.then(null, onRejected)
}

// 示例使用
const promise = new PromiseDemo((resolve, reject) => {
  // 执行异步操作,并在合适的时机调用 resolve 或 reject
  // console.log(resolve, 'resolve')
  setTimeout(() => {
    resolve('返回成功');
  }, 2000);
})

promise
  .then(value => {
    console.log('成功:', value);
    return `${value}1`
  })
  .then(value => {
    console.log('成功1:', value);
  })
复制代码

 class 声明Promise

复制代码
class MyPromise {
  constructor(callback) {
    this.status = "pending";
    this.value = "";
    this.reason = "";
    // 存储成功状态的回调函数
    this.onResolvedCallbacks = [];
    // 存储失败状态的回调函数
    this.onRejectedCallbacks = [];

    
    const resolve = (value) => {
      if (this.status == "pending") {
        this.status = "resolved"
        this.value = value;
        this.onResolvedCallbacks.forEach((fn) => fn());
      }
    }
    const reject = (reason) => {
      if (this.status == "pending") {
        this.status = "rejected"
        this.reason = reason;
        this.onRejectedCallbacks.forEach((fn) => fn());
      }
    }
    try {
      callback(resolve, reject);
    } catch (error) {
      reject(error);
    }

  }

  then(onResolved, onRejected) {
    onResolved = typeof onResolved === "function" ? onResolved : (value) => value;
    onRejected = typeof onRejected === "function" ? onRejected : (reason) => { throw reason };
    // 创建一个新的 Promise 对象
    const promise2 = new MyPromise((resolve, reject) => {
      // 如果当前 Promise 的状态为 resolved
      if (this.status == "resolved") {
        console.log('1111111111')
        try {
           // 执行 onResolved 回调函数
          const x = onResolved(this.value)
          // 处理返回值
          resolve(x)
        } catch (error) {
          // 如果回调函数抛出异常,将异常作为失败状态的值
          reject(error)
        }
      }
      // 如果当前 Promise 的状态为 rejected
      if (this.status == "rejected") {
        console.log('2222222')
        try {
          // 执行 onRejected 回调函数
          const x = onRejected(this.reason)
          // 处理返回值
          resolve(x)
        } catch (error) {
          // 如果回调函数抛出异常,将异常作为失败状态的值
          reject(error)
        }
      }
      // 如果当前 Promise 的状态为 pending
      if (this.status == "pending") {
        console.log('333333333333')
        // 将 onResolved 和 onRejected 保存起来
        // 等待异步操作完成后再执行
        this.onResolvedCallbacks.push(() => {
          if (this.status == "resolved") {
            try {
              // 将上一个then方法的返回值传递给下一个then方法
              const x = onResolved(this.value)
              resolve(x)
            } catch (error) {
              reject(error)
            }
          }
        })
        this.onRejectedCallbacks.push(() => {
          if (this.status == "rejected") {
            try {
              // 将上一个then方法的返回值传递给下一个then方法
              const x = onRejected(this.reason)
              resolve(x)
            } catch (error) {
              reject(error)
            }
          }
        })
      } else {
        // 执行完所有回调函数之后,清空回调数组
        this.onResolvedCallbacks = [];
        this.onRejectedCallbacks = [];
      }
    })
    // 返回新的 Promise 对象
    return promise2
  }
  catch(onRejected) {
    return this.then(null, onRejected)
  }
}

const promise = new MyPromise((resolve, reject) => {
  // setTimeout(() => {
  //     console.log('1')
    resolve('成功')
  // }, 1000)
})
promise.then(1).
then(value => {
  // console.log('2')
  // return "第一次"
  // setTimeout(() => {
    console.log('1', value)
      return "第一次"
  // },1000)
}).then(value => {
  console.log('3', value)
  return "第二次"
  // return new MyPromise((resolve, reject) => {
  //   setTimeout(() => {
  //     resolve('第二次处理结果');
  //   }, 1000);
  // });
}).then(value => {
  console.log(value);
  // throw new Error('抛出异常');
}).catch(error => {
  console.log(error);
});

export default MyPromise;
复制代码

 

posted @   君临天下之徐少  阅读(9)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
点击右上角即可分享
微信分享提示