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方法)。
相关推荐
万少6 小时前
使用Trae轻松安装openclaw的教程-附带免费token
前端·openai·ai编程
浪浪山_大橙子6 小时前
OpenClaw 十分钟快速,安装与接入完全指南 - 推荐使用trae 官方 skills 安装
前端·人工智能
忆江南6 小时前
iOS 可视化埋点与无痕埋点详解
前端
离开地球表面_996 小时前
金三银四程序员跳槽指南:从简历到面试再到 Offer 的全流程准备
前端·后端·面试
_柳青杨6 小时前
跨域获取 iframe 选中文本?自己写个代理中间层,再也不求后端!
前端
比尔盖茨的大脑6 小时前
事件循环底层原理:从 V8 引擎到浏览器实现
前端·javascript·面试
天才熊猫君6 小时前
Vue3 命令式弹窗原理和 provide/inject 隔离机制详解
前端
bluceli6 小时前
Vue 3 Composition API深度解析:构建可复用逻辑的终极方案
前端·vue.js
程序员ys6 小时前
前端权限控制设计
前端·vue.js·react.js
忆江南6 小时前
Flutter GetX 深入浅出详解
前端