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方法)。
相关推荐
mCell16 小时前
如何零成本搭建个人站点
前端·程序员·github
mCell17 小时前
为什么 Memo Code 先做 CLI:以及终端输入框到底有多难搞
前端·设计模式·agent
恋猫de小郭17 小时前
AI 在提高你工作效率的同时,也一直在增加你的疲惫和焦虑
前端·人工智能·ai编程
少云清17 小时前
【安全测试】2_客户端脚本安全测试 _XSS和CSRF
前端·xss·csrf
银烛木18 小时前
黑马程序员前端h5+css3
前端·css·css3
m0_6070766018 小时前
CSS3 转换,快手前端面试经验,隔壁都馋哭了
前端·面试·css3
听海边涛声18 小时前
CSS3 图片模糊处理
前端·css·css3
IT、木易18 小时前
css3 backdrop-filter 在移动端 Safari 上导致渲染性能急剧下降的优化方案有哪些?
前端·css3·safari
0思必得018 小时前
[Web自动化] Selenium无头模式
前端·爬虫·selenium·自动化·web自动化
anOnion18 小时前
构建无障碍组件之Dialog Pattern
前端·html·交互设计