Promise方法存档

Promise.all

实现Promise.all方法:

  1. 接收一个可迭代对象(如数组),返回一个新 Promise;
  2. 所有 Promise 都成功时,返回结果数组(顺序和输入一致);
  3. 任意一个 Promise 失败时,立即返回该失败原因;
  4. 若输入为空数组,立即 resolve 空数组。
js 复制代码
const myPromiseAll = (arrFunc) => {
  return new Promise((resolve, reject) => {
    let resArr = [];
    let len = arrFunc.length;
    let k = 0;
    arrFunc.map((item, index) => {
      Promise.resolve(item).then(
        (res) => {
          k++;
          resArr[index] = res;
          if (k === len) {
            resolve(resArr);
          }
        },
        (rej) => {
          reject(rej);
        }
      );
    });
  });
};
const p1 = Promise.resolve(1);
const p2 = new Promise((resolve) => setTimeout(() => resolve(2), 1000));
const p3 = 3; // 非Promise值

myPromiseAll([p1, p2, p3])
  .then((res) => {
    console.log("all res:", JSON.stringify(res)); // [1,2,3]
  })
  .catch((err) => {
    console.log("all err:", err);
  });
Promise.race

实现Promise.race方法:

  1. 接收可迭代对象,返回新 Promise;
  2. 第一个完成(成功 / 失败)的 Promise 的结果 / 原因,就是最终结果;
  3. 若输入为空数组,永远 pending
js 复制代码
const MyPromiseRace = (arrFunc) => {
  return new Promise((resolve,reject) => {
    arrFunc.map(item => {
      Promise.resolve(item).then(res=>{
        resolve(res)
      },rej=>{
        reject(rej)
      })
    });   
  });
};

const p1 = Promise.resolve(1);
const p2 = new Promise((resolve) => setTimeout(() => resolve(2), 1000));
const p3 = 3; // 非Promise值

const p4 = Promise.reject(new Error('fail'));
MyPromiseRace([p1, p4]).catch(err => {
  console.log('all err:', err.message); // fail
});
Promise.allSettled

实现Promise.allSettled方法:

  1. 接收可迭代对象,返回新 Promise;
  2. 所有 Promise 都完成(成功 / 失败)后,返回结果数组;
  3. 每个结果对象格式:{ status: 'fulfilled', value: xxx }{ status: 'rejected', reason: xxx }
  4. 空数组立即 resolve 空数组
js 复制代码
const MyPromiseAllSettled = (arrFunc)=>{
  return new Promise((resolve,reject)=>{
    let len = arrFunc.length
    let resarr = []
    let k = 0

    arrFunc.map((item,index)=>{
      Promise.resolve(item).then(res=>{
        k++
        resarr[index] = res
        if(len === k){
          resolve(resarr)
        }
      },rej=>{
        k++
        resarr[index] = rej
        if(len === k){
          resolve(resarr)
        }
      })
    })
  })
}
const p1 = Promise.resolve(1);
const p2 = new Promise((resolve) => setTimeout(() => resolve(2), 1000));
const p3 = 3; // 非Promise值

const p4 = Promise.reject(new Error('fail'));
MyPromiseAllSettled([p1,p2,p3, p4]).then(res => {
  console.log('all err:', res); // fail
});
实现异步函数串行执行(基于 Promise)

给定一个异步函数数组(每个函数返回 Promise),实现一个函数,让这些函数串行执行(前一个完成后,再执行后一个),最终返回所有结果的数组。

js 复制代码
const AsyncPromiseArr = (arrFunc) => {
  return new Promise(async(resolve, reject) => {
    const stack = [];
    let i = 0
    for(let func of arrFunc){
      const res = await func();
      stack.push(res);
      i++
      if(i === arrFunc.length){
        resolve(stack)
      }
    }
  });
};

// 测试用例
// 模拟异步函数
const task1 = () => new Promise(resolve => setTimeout(() => resolve(1), 500));
const task2 = () => new Promise(resolve => setTimeout(() => resolve(3), 1500));
const task3 = () => new Promise(resolve => setTimeout(() => resolve(2), 100));

AsyncPromiseArr([task1, task2, task3]).then(res => {
  console.log('serial res:', res); // [1,2,3](执行顺序:task1→task2→task3)
});
实现 Promise 超时封装

实现一个函数withTimeout(promise, timeout, errMsg)

  1. 给 Promise 添加超时控制,若超过timeout毫秒未完成,返回 reject(错误信息为errMsg);
  2. 若 Promise 在超时前完成,正常返回结果;
  3. 超时后终止等待(无需取消原 Promise,仅控制返回结果)。
js 复制代码
const withTimeout = (promise,timeout,errMsg)=>{
  const promise1 = new Promise((resolve,reject)=>{
    setTimeout(()=>reject(new Error(errMsg)),timeout)
  })
  return Promise.race([promise,promise1])
}

const p1 = new Promise(resolve => setTimeout(() => resolve(100), 500));
withTimeout(p1, 1000, '超时了').then(res => {
  console.log('timeout res:', res); // 100
});

// 超时场景
const p2 = new Promise(resolve => setTimeout(() => resolve(200), 1500));
withTimeout(p2, 1000, '超时了').catch(err => {
  console.log('timeout err:', err.message); // 超时了
});
实现一个防抖函数

触发事件后,第一次触发立即执行,后续延迟 n 毫秒执行回调函数 ;如果在这 n 毫秒内再次触发事件,重置延迟时间 ,同时增加cancel方法支持手动取消

js 复制代码
const debounce_ = (fn,delay)=>{
  let fn_
  const debounceFunc = function(...args){
    if(fn_){
      clearTimeout(fn_)
    }else{
      fn.call(this,...args)
    }
    fn_ = setTimeout(()=>{
      fn.call(this,...args)
      fn_ = null
    },delay)
  }
  debounceFunc.cancel = function(){
    clearImmediate(fn_)
    fn_ = null
  }
  return debounceFunc
}

function handleSearch(val) {
  console.log('搜索:', val);
}

const debouncedSearchImmediate = debounce_(handleSearch, 1000);
debouncedSearchImmediate('a'); // 立即输出「搜索:a」
debouncedSearchImmediate('ab'); // 500ms内触发,重置定时器(无输出)
setTimeout(() => {
  debouncedSearchImmediate('abc'); // 500ms后触发,立即输出「搜索:abc」
},2000);

// 测试取消功能
const debouncedCancel = debounce_(handleSearch, 500);
debouncedCancel('test');
debouncedCancel.cancel(); 
实现节流函数

触发事件后,每隔 n 毫秒只能执行一次回调函数,无论期间触发多少次,都会按固定频率执行

js 复制代码
const throttle_ = (fn, delay) => {
  let timer;
  return function (...args) {
    if (!timer) {
      timer = setTimeout(() => {
        fn.call(this, ...args);
        timer = null
      }, delay);
    }
  };
};
实现带 Promise 的防抖函数

实现一个防抖函数debounceWithPromise(fn, delay)

  1. 触发后延迟delay毫秒执行函数;
  2. 重复触发时重置延迟;
  3. 函数执行结果通过 Promise 返回;
  4. 支持取消防抖(添加cancel方法)。
相关推荐
weixin_493503677 小时前
Vue3 前端生成 PDF:会员证书与活动签到表的三种打印方案与踩坑记录
前端·pdf·状态模式
尾善爱看海10 小时前
前端算法与手写题集
前端·算法
徐小夕10 小时前
JitWord 4.0 万字分享:从协同工具到AI Word操作系统,聊聊3年产品创业史
前端·vue.js·后端
萧鼎12 小时前
Python 高性能Web框架神器 FastAPI:自动生成API文、基于Pydant、异步请求处理全搞定
前端·python·fastapi
IT_陈寒13 小时前
Redis误用keys命令把生产环境搞崩了,血的教训
前端·人工智能·后端
计算机魔术师13 小时前
5000亿估值冲刺科创板,DeepSeek 为何急着上市?
前端
我血条子呢13 小时前
前端解析word方案
前端·word
kyriewen13 小时前
我用 AI 写完一个需求后才发现,最难的不是 prompt,而是验收
前端·程序员·ai编程
申行13 小时前
Vue 3 + DYMO Connect Framework 实战:从标签模板到打印服务的完整实现
前端
两只羊ovo13 小时前
Vue 3 + DeepSeek 流式输出实战:从“干等”到“打字机”体验
前端·vue.js