PayPal Smart Button对接Firestore时Promise返回值与执行顺序异常问题
问题1解答
确实是Promise异步未等待导致的。Firestore的get()方法是异步调用,执行后会立刻返回Promise,不会等接口查询结果返回就会继续执行后续代码,所以写在then()回调外部的console.log('Third Creation')会最先执行。同时paypalCreate是你在then()内部声明的局部变量,外部作用域根本访问不到,所以打印值为undefined。
问题2解答
成功场景下Second Creation没有打印是代码语法错误导致:你在else分支里执行完订阅创建逻辑后直接写了return paypalCreate,函数遇到return会直接终止执行,后面的console.log('Second Creation')永远不会被触发。另外你写的Firestoreset()方法后面用了逗号而非分号,也会导致异步逻辑链断裂,容易出现用户未存入Firestore但订阅已创建的脏数据问题。
问题3解决方法
PayPal的createSubscription本身支持返回Promise,你可以用async/await改写逻辑,保证所有异步操作按顺序执行完成后再返回结果,修正后的代码如下:
createSubscription: async function(data, actions) { // 等待用户存在性查询完成 const querySnapshot = await db.collection('users').doc(email).get(); if (querySnapshot.exists) { console.log('First Creation error'); // 抛出错误供上层捕获处理 throw new Error('用户已存在,无需重复注册'); } console.log("用户不存在,开始创建用户记录"); // 等待用户记录写入Firestore完成再创建订阅 await db.collection('users').doc(email).set({ name: name, email: email, created: firebase.firestore.Timestamp.now() }); // 等待PayPal订阅创建完成返回结果 const paypalCreate = await actions.subscription.create({ 'plan_id': 'XXXX' }); console.log('First Creation success', paypalCreate); return paypalCreate; }
改写后后续流程可以直接拿到返回的订阅ID,用户已存在的报错可以在PayPal的onError回调中捕获处理。
内容的提问来源于stack exchange,提问作者danniel
相关产品推荐
相关产品推荐

