手写Promise类实现:构造函数入参f的指代疑问
传参层级的核心误区
你混淆了两次函数调用的传参关系,不存在“传进去的是resolve而非f”的情况,整个流程的传参逻辑是完全分层的:
构造函数的入参定义
这个自定义Promise类的构造函数明确要求:执行new Promise()时,必须传入1个函数作为唯一实参,这个实参在构造函数内部的形参名就叫f。
你写的实例化代码:
let promise = new Promise(resolve => { myFunc(); })
这里紧跟在new Promise()括号里的完整箭头函数resolve => { myFunc(); },就是构造函数接收到的f。你误以为是入参的resolve,只是这个箭头函数自己的形参占位名,根本不是传给Promise类的内容。
resolve的实际来源
这个resolve不是你提供的,是Promise构造函数内部自己生成的。对照构造函数的源码逻辑可以看得很清楚:
constructor(f) { this.onResolves = []; this.status = "pending"; // 这部分是类内部自行定义的resolve函数 const resolve = value => { this.status = "resolved"; this.value = value; this.callOnResolves(); }; // 把内部生成的resolve,作为参数传给你传入的f函数执行 f(resolve); }
整个执行顺序是固定的:
- 你把写好的箭头函数作为唯一实参传给
new Promise(),这个函数在构造函数内部被赋值给变量f - 构造函数初始化内部属性:存储then回调的数组、初始pending状态
- 构造函数在内部生成专属的
resolve函数,这个函数的作用是把状态改成resolved、保存返回值、触发所有绑定的then回调 - 构造函数拿着自己生成的
resolve,作为实参调用你传进来的f函数,这个时候你写的箭头函数的形参才会被赋值,函数体里的myFunc()才会执行
逻辑验证
你完全可以把箭头函数的形参名改成任意其他值,整个逻辑不会有任何变化——因为这个形参只是用来接收类内部传值的占位符:
// 把形参改名叫done,效果完全一致 let promise = new Promise(done => { myFunc(); // 这里的done就是类内部生成的那个resolve done('myFunc执行完成') })
注:你写的实例化代码存在语法遗漏,箭头函数的代码块少了一个闭合的花括号和右括号,实际运行会报语法错误,正确写法需要在末尾补上闭合符号。
内容的提问来源于stack exchange,提问作者GrgHughes55
相关产品推荐
相关产品推荐

