一、需求
点击按钮处理重复提交,想要通过disabled的方式实现。
但是点击按钮调用的方法里有ajax、跳转、弹窗等一系列逻辑操作,需要等方法里流程都走完,再把disabled设为false,这样下次点击按钮时就可以继续走方法里的ajax等操作。
ajax请求需要时间返回,需要等返回后才能把disabled设为false,这就要保证点击按钮里的方法是同步执行的;
ajax.then.then的实现方法嵌套的太多,可以使用async 和 await代替,async是异步的,需要靠 await达到同步效果。
二、实现
addPaper里的所有操作,不管层级如何,每个都要使用async 和 await,保证代码都是同步执行的;
不是同步执行的话,ajax还没返回,就执行了下面的disabled=false,重复提交时拦截不住的。
保证了代码是同步执行的,就可以在addPaper.then里一个位置将disabled=false,不用在addPaper里每个位置都设置addPaper。
Builder.init({disabled:false //初始定义disabled为false,点击按钮时,可以继续执行方法里的操作
})
.method("onItemClick",function(e){// disabled=true,表示已经点击此按钮,并且此方法并未执行完成,直接return先不继续执行if(this.data.disabled){return false;}this.data.disabled = true //disabled=true,保证下次点击时拦截继续执行this.addPaper({jobid:item.JobId,dimensionid:'',interviewtype:1,checkexistinterview:1}).then(function(result){// addPaper里使用async和await,保证方法都是同步执行的,这里then方法里将disabled=false,表示点击按钮可以继续执行了that.data.disabled = false})
}) .method("addPaper",async function(args){let that = thisawait checkSession.getAppSession().then(async function(sessionKey){if(!util.session.signKey){await wx.navigateTo({url: '/pages/login/login?curjobid='+args.jobid+'&interviewtype='+args.interviewtype+'&dimensionid='+args.dimensionid,success:(e)=>{that.data.disabled = false},});}else{await that.toAddPaper(args)}})})builder.method("toAddPaper", async function (args) {let that = this;await http.promiseRequest({url: "/aivideo/addTempPaper",method: "POST",data: {},}).then(async (result)=>{});
})
延伸:
ajax是比较友好的一种方式,ajax通过async 和 await是可以实现同步的,addPaper里有wx.navigateTo跳转、微信wx.authorize授权摄像头、wxModel弹窗等时,就需要在addPaper内部在每一个位置添加disabled=false。
1、wx.navigateTo在跳转succes里添加disabled=false
2、wxModel弹窗,因为弹窗出来流程就走完了,直接弹窗位置加上disabled=false即可。
3、wx.authorize,就直接弹出来授权窗口了,在哪里加上disabled=false呢,授权窗口无非就同意和拒绝,在success同意和fail拒绝里加上disabled=false即可
二、原理
async
和 await
是 JavaScript 中用于处理异步操作的关键字,它们让代码更加简洁和易于理解,避免了传统的回调函数(callback)或 .then()
链式调用所带来的复杂性。async
和 await
是基于 JavaScript 的 Promise 的语法。
1. async
函数
async
关键字用来定义一个异步函数,表示该函数内部会有异步操作。异步函数总是返回一个 Promise
,即使函数内部没有明确使用 return
返回一个 Promise,JavaScript 会自动把函数返回值包装在一个已解析的 Promise 中。
async function myFunction() {return 'Hello, world!';
}myFunction().then(result => {console.log(result);
});
2. await
表达式
await
关键字只能在 async
函数内部使用,它用于等待一个 Promise
解析(resolve)并返回解析后的结果。如果 await
后面的表达式不是一个 Promise,那么它会自动将其转换为一个已解析的 Promise。
async function fetchData() {let response = await fetch('https://api.example.com/data');let data = await response.json();return data;
}fetchData().then(data => {console.log(data); // 输出从 API 获取的 JSON 数据
});
3. async
和 await
的工作原理
- 当执行
await
时,JavaScript 会暂停函数的执行,直到Promise
解析(resolve)或者拒绝(reject)。 - 如果
Promise
被成功解析,await
会返回该值,函数会继续执行。 - 如果
Promise
被拒绝,await
会抛出一个错误(相当于抛出Promise.reject()
的错误),你可以使用try...catch
来捕获和处理这个错误。
4. 使用 try...catch
捕获错误
在处理异步操作时,我们通常会使用 try...catch
来捕获潜在的错误(例如网络请求失败等)。
示例
async function fetchData() {try {let response = await fetch('https://api.example.com/data');if (!response.ok) {throw new Error('Network response was not ok');}let data = await response.json();return data;} catch (error) {console.error('Fetch error:', error);}
}fetchData();
5. 组合多个异步操作
你可以在 async
函数中使用多个 await
来依次执行多个异步操作。需要注意的是,await
会按顺序依次等待每个 Promise
完成,这可能导致不必要的延迟。如果有多个独立的异步操作,可以考虑并行执行它们。
示例:依次执行多个异步操作
async function fetchData() {let userResponse = await fetch('https://api.example.com/user');let userData = await userResponse.json();let postsResponse = await fetch(`https://api.example.com/posts?userId=${userData.id}`);let postsData = await postsResponse.json();return { userData, postsData };
}fetchData().then(data => console.log(data));
示例:并行执行多个异步操作
javascript
async function fetchData() {let userPromise = fetch('https://api.example.com/user');let postsPromise = fetch('https://api.example.com/posts');let [userResponse, postsResponse] = await Promise.all([userPromise, postsPromise]);let userData = await userResponse.json();let postsData = await postsResponse.json();return { userData, postsData };
}fetchData().then(data => console.log(data));
在这个例子中,Promise.all()
会并行执行两个请求,只有在两个请求都完成后,才会继续进行数据解析。这样可以提高效率,避免等待一个请求完成后再去发送另一个请求。
总结
async
:用来声明异步函数,返回一个 Promise。await
:用来等待一个 Promise 被解析,通常与async
配合使用。- 异常处理可以使用
try...catch
捕获和处理。 - 可以使用
Promise.all()
来并行执行多个异步操作,避免串行执行造成的性能瓶颈。
async/await
使得异步代码的书写更加简洁直观,避免了回调地狱和 .then()
链式调用的层层嵌套,提升了代码的可读性和维护性。
二、wx跳转