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方法)。
相关推荐
恋恋风尘hhh2 小时前
滑动验证码前端安全研究:以顶象(dingxiang-inc)为例
前端·安全
懂懂tty9 小时前
React状态更新流程
前端·react.js
小码哥_常9 小时前
告别繁琐!手把手教你封装超实用Android原生Adapter基类
前端
skywalk81639 小时前
pytest测试的时候这是什么意思?Migrating <class ‘kotti.resources.File‘>
前端·python
一只蝉nahc10 小时前
vue使用iframe内嵌unity模型,并且向模型传递信息,接受信息
前端·vue.js·unity
子兮曰10 小时前
Bun v1.3.12 深度解析:新特性、性能优化与实战指南
前端·typescript·bun
2401_8858850411 小时前
易语言彩信接口怎么调用?E语言Post实现多媒体数据批量下发
前端
a11177611 小时前
Three.js 的前端 WebGL 页面合集(日本 开源项目)
前端·javascript·webgl
Kk.080211 小时前
项目《基于Linux下的mybash命令解释器》(一)
前端·javascript·算法
小李子呢021112 小时前
前端八股---闭包和作用域链
前端