electron如何利用await解决smalltalk对话框异步执行的问题
发布于 作者:苏南大叔 来源:程序如此灵动~在上一篇smalltalk
的文章中,大家可以了解到:类似smalltalk
模拟对话框类的代码,有一个通病,就是说,对话框的显示,是个异步的过程,并不会阻塞js进程。也就是说如果期待一个逻辑在alert
完成之后,再执行的话。那么在smalltalk
类里面就是个非常难以解决的问题。
因为如果安装老的思路来写代码的话,smalltalk
对话框显示出来之后,下面的js逻辑还是会继续执行的,并不会被smalltalk.alert()
阻塞在代码逻辑中。这个问题,终于最近有了答案,就是js的async/await
。这个天然用于阻塞js进程的好cp组合。大家请跟随苏南大叔的描述,继续学习一下async/await
在smalltalk
中的使用。
smalltalk
对话框不阻塞进程
苏南大叔对上一篇smalltalk
文章中的例子,做了点小小的改动。代码如下:
var smalltalk = require ('smalltalk/legacy');
console.log("before prompt");
smalltalk.prompt('newsn.net提示您', '这个是苏南大叔测试的prompt范例', 'easy~')
.then(function(value) {
console.log(value);
}, function() {
console.log('close');
});
console.log("before alert");
smalltalk.alert('newsn.net提示您', '这个是苏南大叔测试的alert范例')
.then(() => {
console.log('ok');
});
console.log("before confirm");
smalltalk.confirm('newsn.net提示您', '您看明白了嘛?')
.then(() => {
console.log('yes');
})
.catch(() => {
console.log('no');
});
console.log("end all");
从运行结果上,我们就可以看出:在界面上,还停留在第一个对话框,但是从console上面看,程序已经执行完毕。
改造版smalltalk
苏南大叔对smalltalk
的三个函数,用async/await
进行了包装,可以优雅地解决阻塞js进程的问题。
下面可以复习一下async/await
的主要要点,不知道官方说法是怎么样的,下面的经验就是苏南大叔自己总结的:
await
后面的函数必须是个promise
,也就是说会带着.then()
的一个函数。await
必须包裹在一个async
修饰的异步函数内。
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/await
https://www.jianshu.com/p/78dfb38ac3d7
下面的这个包装,苏南大叔只是想包装的更加接近于传统的alert系列的写法罢了,毕竟传统的alert是通过返回值来做下一步判断的,而不是then()
系列。所以,您使用本来就可以的await
也是ok的,没有必要像下面这样包装。下面的包装,仅仅是个怀旧版本的包装罢了。
所以,通过async/await
改造过的smalltalk
代码如下:
<link rel="stylesheet" href="./node_modules/smalltalk/css/smalltalk.css">
<!--<script src="./node_modules/smalltalk/dist/smalltalk.poly.min.js"></script>-->
<script>
var smalltalk = require ('smalltalk/legacy');
async function alert (title,msg){
return await smalltalk.alert(title,msg)
.then(() => {
return true;
}).catch((err) => {
return false;
});
}
async function confirm (title,msg){
return await smalltalk.confirm(title,msg)
.then(() => {
return true;
}).catch((err) => {
return false;
});
}
async function prompt (title,msg,hint){
return await smalltalk.prompt(title,msg,hint)
.then((value) => {
return value;
})
.catch(() => {
return false;
});
}
;(async()=>{
var a = await prompt('newsn.net提示您', '这个是苏南大叔测试的prompt范例', 'easy~');
var b = await confirm('newsn.net提示您', 'promot 返回值是:'+a);
await alert('newsn.net发现您点击了:', b?"确定":"取消");
})();
这里值得注意的是:对于不支持require
函数的普通浏览器,我们需要用普通的script标签引入smalltalk.poly.min.js
。在electron
中,需要开启browser的node支持,才可以正常使用require
函数。而async/await/promise
,在目前最新的chrome浏览器里面,支持性都是很好的。至于ie系列浏览器,鉴于其超强的自暴自弃性,苏南大叔也就暂时不考虑ie系列了。
截图特别说明
从调用的结果截图上看,每个的smalltalk
对话框都得到了上一个对话框的返回值,也就是说对话框变成阻塞式的了。相对于原始的alert/confirm/promot
写法,这里的区别除了函数包装外,还有区别的就是如下字样:
;(async()=>{
var <对话框返回值> = await <被包装过的函数>
})();
结论
本文的调试环境为:win10 + electron(渲染进程)。整体来说,使用async/await
包装了smalltalk
,然后用覆写了系统函数alert/confirm/promot
,就可以完全定制系统对话框了。
美中不足的是:
- 所有的代码逻辑必须放置在一个匿名的异步函数
async
里面,才可以正常执行。 - 在
alert/confirm/promot
前面必须增加个await
字样,才可以阻塞进程。
更多await相关经验内容,请点击苏南大叔的博客。https://newsn.net/tag/await/ 。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。
真蠢,本身就能await,还包装一层干什么
小兄弟,真知灼见~ 赞~