• 作者:老汪软件技巧
  • 发表时间:2024-10-14 07:01
  • 浏览量:

编程小知识

开始写手写 Promise 相关函数之前我会讲一些前置小编程知识(常被开发者忽视,如果都了解可以跳过这一部分)

大家好,我是芝士,欢迎点此扫码加我微信Hunyi32交流,最近创建了一个低代码/前端工程化交流群,欢迎加我微信 Hunyi32 进群一起交流学习,也可关注我的公众号[ 前端界 ] 持续更新优质技术文章

函数签名

手写一个函数时,第一步应该考虑的是函数签名!什么是函数签名?

函数功能:函数的单一职责是什么,先确定好。函数名称:符合单一职责的函数名称,让使用者通过名称可以清楚知道函数作用,不用关心函数内部实现函数参数: 函数参数定义,与名称相同,语义明确函数返回值: 注意是否有返回值,以及明确内容

这里我更推荐 TypeScript, TypeScript 对参数类型,返回值类型等约束的比较到位。

这四点是你在写一个函数时应该重点考虑的内容,一个优秀的函数是不需要使用者关心函数内部实现的。你可以看看 MDN 中函数的实现,举个例子:Array.prototype.findIndex 这种语义就很明确,使用者不需要关心内部实现。

好了接下来回到本文主题,手写大厂面试常考的面试题 Promise.all 和 Promise.race。在实现这两个函数时候不要忘记我前面提到的函数签名知识点。

Promise.allPromise.all 函数签名Promise.all 的功能介绍

Promise.all 是一个 JavaScript Promise 方法,它接收一个可迭代对象(如数组或类数组对象)作为参数,并返回一个新的 Promise 对象。

Promise.all 的作用是在给定的可迭代对象中的所有 Promise 都完成时,返回一个包含所有 Promise 结果的新 Promise 对象。如果可迭代对象中的任何一个 Promise 被拒绝(rejected),则返回的 Promise 对象会立即被拒绝,并且会带有被拒绝的 Promise 的原因。

简而言之,Promise.all 可以将多个 Promise 并行执行,并在所有 Promise 都完成时返回一个包含所有结果的 Promise 对象。

函数名:手写现有函数 仍然使用 all 函数参数:一个可迭代对象返回值:返回的是一个 promise 对象

特殊说明点:

开始编码阶段阶段一:Promise.all 一定返回返回一个Promise对象

Promise.myAll = (promiseIterator)=>{
    let res,rej;
    const p = new Promise((resolve,reject)=>{
        res = resolve;
        rej = reject;
    })
    return p;
}

阶段二:临界场景 如果传入一个空的迭代器,返回什么?

这里特殊说一下,因为原生 Promise.all 函数中接受的是一个迭代器对象,并非数组。所以使用 for of 遍历记录 count 数量。看网上很多手写 Promise.all 文章没有考虑到这点。

Promise.myAll = (promiseIterator)=>{
    let res,rej;
    const p = new Promise((resolve,reject)=>{
        res = resolve;
        rej = reject;
    })
    const result = [];
    let count = 0;
    for (const iterator of promiseIterator) {
        count ++;
    }
    if(count === 0){
        res(result);
    }
    return p;
}

阶段三:for 循环中执行每一个 promise

这里执行每一个 promise,使用的 Promise.resolve

_跳过前置摄像头_前置任务怎么跳过

Promise.myAll = (promiseIterator)=>{
    let res,rej;
    const p = new Promise((resolve,reject)=>{
        res = resolve;
        rej = reject;
    })
    const result = [];
    let count = 0;
    for (const iterator of promiseIterator) {
        count ++;
        Promise.resolve(iterator).then((r)=>{
            
        },(reason)=>{
           rej(reason)
        })
    }
    if(count === 0){
        res(result);
    }
    return p;
}

记录完成的promise,如果全部完成将最终结果resolve

这里有注意点:

Promise.all 参数传入的可迭代器对象,经过 Promise.all 执行完成后,最终返回的结果要和入参时的顺序相同,所以需要有一个遍历记录 promise 执行的索引,确保放入到 result 数组中顺序相同,返回的顺序也相同需要有变量记录全部 fullFilled 完成的 promise 。全部完成时 resolve(result);如果 fullFilled 状态失败 也要返回 reject(result);

Promise.myAll = (promiseIterator)=>{
    let res,rej;
    const p = new Promise((resolve,reject)=>{
        res = resolve;
        rej = reject;
    })
    const result = [];
    let count = 0;
    let fulledCount = 0;
    for (const iterator of promiseIterator) {
        let i = count;
        count ++;
        Promise.resolve(iterator).then((r)=>{
            result[i] = r;
            fulledCount ++;
            if(fulledCount === count){
                res(result)
            }
        },(reason)=>{
           rej(reason)
        })
    }
    if(count === 0){
        res(result);
    }
    return p;
}

Promise.all 完整代码

Promise.myAll = (promiseIterator)=>{
    let res,rej;
    const p = new Promise((resolve,reject)=>{
        res = resolve;
        rej = reject;
    })
    const result = [];
    let count = 0;
    let fulledCount = 0;
    for (const iterator of promiseIterator) {
        let i = count;
        count ++;
        Promise.resolve(iterator).then((r)=>{
            result[i] = r;
            fulledCount ++;
            if(fulledCount === count){
                res(result)
            }
        },(reason)=>{
           rej(reason)
        })
    }
    if(count === 0){
        res(result);
    }
    return p;
}

测试验证

const promise1 = Promise.resolve(1);
const promise2 = Promise.resolve(2);
const promise3 = Promise.resolve(3);
Promise.all([promise1, promise2, promise3])
  .then((results) => {
    console.log(results); // 输出: [1, 2, 3]
  })
  .catch((error) => {
    console.error(error);
  });

Promise.racePromise.race 函数签名Promise.race 的功能介绍

Promise.race 的作用是在给定的可迭代对象中的任何一个 Promise 完成(无论是解决还是拒绝)时,返回一个新的 Promise 对象。返回的 Promise 对象将具有第一个完成的 Promise 的结果或原因。

划重点:无论解决还是拒绝简而言之,Promise.race 可以将多个 Promise 并行执行,并返回一个新的 Promise 对象,该对象将具有第一个完成的 Promise 的结果或原因。

函数名:手写现有函数 仍然使用 race 函数参数:一个可迭代对象 iterator返回值:返回的是一个 promise 对象特殊说明点:编码实现返回一个promise对象

Promise.race = (promiseIterator)=>{
    let res,rej
    const p = new Promise((resolve,reject)=>{
        res = resolve;
        rej = reject;
    })
    return p;
}

竞赛,不管任何一个先完成都要立即返回

Promise.race = (promiseIterator)=>{
    let res,rej
    const p = new Promise((resolve,reject)=>{
        res = resolve;
        rej = reject;
    })
    for (const prom of promiseIterator) {
        Promise.resolve(prom).then(value=>{
            res(value)
        },(reason)=>{
            rej(reason)
        })
    }
    return p;
}

测试验证

const promise1 = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve('Promise 1 resolved');
    }, 1000);
});
const promise2 = new Promise((resolve, reject) => {
    setTimeout(() => {
        reject(new Error('Promise 2 rejected'));
    }, 2000);
});
Promise.race([promise1, promise2])
.then((result) => {
    console.log(result); // 输出: Promise 1 resolved
})
.catch((error) => {
    console.error(error); // 不会执行,因为 promise1 先完成
});

大家好,我是芝士,最近创建了一个低代码/前端工程化交流群,欢迎点此扫码加我微信Hunyi32交流,也可关注我的公众号[ 前端界 ] 持续更新优质技术文章

Promise.any 和 Promise.allSettled

Promise.any

Prmise.allSettled

这两个函数具体实现就不写了,只说明一下作用和使用场景,留个作业,小伙伴们可以实现一下评论区回复哦!创作不易,感谢大家点赞,转发!


上一条查看详情 +锐评 Nodejs 设计模式 - 创建与结构型
下一条 查看详情 +没有了