接上,让Promise将结果传递下去

上文:Promise初始用

https://blog.youkuaiyun.com/cau_eric/article/details/148129017?spm=1001.2014.3001.5501

新需求:

中奖和未中奖弹框时将当时抽中的号码显示出来。

这个时候,我们可以用resolve和reject将随机数往下传。

然后调用then的时候将它们取出来使用。

新改的代码:

prizeDraw(){
    const p = new Promise((resolve,reject) => {
      setTimeout(() => {
        let n = Math.floor(Math.random()*100)+1;
        if (n <= 30) {
          resolve(n);
        } else {
          reject(n);
        }
      }, 1000);
    });

    p.then((value) => {
      wx.showModal({
        title: '恭喜恭喜',
        content: '奖品为 10 万 RMB 劳斯莱斯优惠券,您的中奖号码是 ' + value,
        showCancel: false, // 隐藏取消按钮
        confirmText: '我知道了',
      });
    },(reason) => {
      wx.showModal({
        title: '没抽中',
        content: '再接再厉,您的号码是:' + reason,
        showCancel: false, // 隐藏取消按钮
        confirmText: '我知道了',
      });
    });
  }

效果:

<think>嗯,用户想了解如何手动实现JavaScript的Promise。首先,我得回忆一下Promise的基本工作原理。Promise是用于处理异步操作的对象,有三种状态:pending、fulfilled和rejected。状态一旦改变就不能再变。 首先,我需要定义一个类,比如MyPromise。构造函数接收一个执行器函数,执行器里会调用resolve和reject。这两个函数需要改变状态,并且处理回调。因为then方法可以多次调用,所以需要存储回调函数,可能用数组来保存。 然后,resolve和reject函数要负责改变状态,并且执行相应的回调。这里要注意,异步操作完成后才会触发回调,所以可能需要用setTimeout或者微任务机制来异步执行回调。不过手动实现的话,可能先用setTimeout模拟。 接下来是then方法的实现。then方法需要接收onFulfilled和onRejected两个参数,并且返回一个新的Promise,以实现链式调用。这时候要考虑如果onFulfilled不是函数的话,应该设置默认函数,将值传递下去。同时,需要处理回调的执行结果,如果是Promise的话,需要等待它的状态改变。 另外,错误处理也很重要。如果在执行过程中抛出异常,应该捕获并传递给下一个reject。比如在执行器函数或者then的回调中出现的错误,都需要被正确处理。 还要处理同步和异步的情况。比如,如果执行器里同步调用了resolve,那么then方法添加的回调应该还是异步执行。这可能需要用队列来管理回调,确保它们按顺序执行。 可能还需要实现catch方法,其实就是then方法的特例,只处理rejected的情况。还有finally方法,不过用户的问题可能暂时不需要这个。 测试的时候,用户给出的例子中有多个then调用,并且有setTimeout。所以在实现时,必须确保then的回调在resolve被调用后才会执行,并且多个then的回调都能被正确触发。 此外,链式调用中的返回值如果是Promise,需要等待它解决。这部分可能需要递归处理,直到得到一个非Promise的值,或者最终状态。 可能遇到的难点包括状态管理的原子性,确保一旦状态改变就不会再变,以及正确处理异步回调的顺序。还有链式调用中每个then返回新Promise的处理逻辑,需要正确地将前一个的结果传递给下一个。 总结步骤大概是: 1. 定义MyPromise类,初始化状态和值。 2. 实现resolve和reject方法,改变状态并执行回调。 3. 实现then方法,收集回调,返回新Promise。 4. 处理回调的返回值,支持链式调用。 5. 错误处理和异步执行。 需要参考用户提供的引用,比如引用[3]中的例子,确保实现的MyPromise能正确处理多个then的调用,并在setTimeout后执行。同时,引用[2]提到then返回Promise,所以链式调用需要正确处理返回的Promise。 可能还需要实现其他方法如catch和静态方法如resolve、reject、all等,但根据用户的问题,主要关注then和基本结构。 最后,代码示例要符合规范,正确使用$和$$格式,确保LaTeX语法正确,比如在提到状态时用$...$包裹变量。</think>### 手动实现 JavaScript Promise 的方法 #### 1. Promise 的核心原理 Promise 是用于管理异步操作的对象,包含三种状态:$pending$(等待)、$fulfilled$(成功)和$rejected$(失败)。状态一旦改变不可逆。实现需满足以下特性: - **链式调用**:通过 `then` 方法返回新 Promise 实现链式操作[^2] - **异步执行**:回调函数需异步触发(如通过 `setTimeout` 模拟微任务) - **错误冒泡**:若未定义错误处理,错误会向下传递直到被捕获 #### 2. 基础框架实现 ```javascript class MyPromise { constructor(executor) { this.state = 'pending'; // 初始状态 this.value = undefined; // 成功值/失败原因 this.onFulfilledCallbacks = []; // 成功回调队列 this.onRejectedCallbacks = []; // 失败回调队列 const resolve = (value) => { if (this.state === 'pending') { this.state = 'fulfilled'; this.value = value; this.onFulfilledCallbacks.forEach(fn => fn()); // 异步触发回调 } }; const reject = (reason) => { if (this.state === 'pending') { this.state = 'rejected'; this.value = reason; this.onRejectedCallbacks.forEach(fn => fn()); } }; try { executor(resolve, reject); // 立即执行执行器函数 } catch (err) { reject(err); // 捕获同步错误 } } } ``` #### 3. `then` 方法实现 ```javascript then(onFulfilled, onRejected) { // 默认值穿透处理 onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : v => v; onRejected = typeof onRejected === 'function' ? onRejected : err => { throw err }; const promise2 = new MyPromise((resolve, reject) => { const handleCallback = (callback, value) => { setTimeout(() => { // 模拟微任务 try { const x = callback(value); resolvePromise(promise2, x, resolve, reject); } catch (err) { reject(err); } }); }; if (this.state === 'fulfilled') { handleCallback(onFulfilled, this.value); } else if (this.state === 'rejected') { handleCallback(onRejected, this.value); } else { // pending 状态时存储回调 this.onFulfilledCallbacks.push(() => handleCallback(onFulfilled, this.value)); this.onRejectedCallbacks.push(() => handleCallback(onRejected, this.value)); } }); return promise2; // 返回新 Promise 实现链式调用 } ``` #### 4. 解决回调返回值 ```javascript function resolvePromise(promise2, x, resolve, reject) { if (x === promise2) { return reject(new TypeError('Chaining cycle detected')); } if (x instanceof MyPromise) { x.then(resolve, reject); // 递归处理 Promise 返回值 } else { resolve(x); // 直接传递普通值 } } ``` #### 5. 测试用例 ```javascript const p = new MyPromise((resolve) => { setTimeout(() => resolve("ok"), 1000); }); p.then(res => console.log(res + 1)) // 输出 "ok1" .then(() => new MyPromise(resolve => resolve(100))) .then(num => console.log(num)); // 输出 100 ``` #### 关键点总结 - **状态隔离**:每个 `then` 返回的新 Promise 独立管理状态 - **异步队列**:通过回调队列处理异步操作和多次调用 `then` 的场景[^3] - **错误处理**:通过 `try/catch` 捕获同步/异步错误 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值