作者:貘吃馍香
链接:http://www.zhihu.com/question/20963787/answer/34123046
来源:知乎
著作权归作者所有,转载请联系作者获得授权
第一个比较简单。
首先它是目标平台的包装函数,也就是非JS原生 API。
这需要调用JS 引擎的包装方法来作,也就是JS引擎(一般是C++ Lib)会给出一些用来把目标平台业务API(函数)包装为可使用JS语法调用的机制。
比如 Qt C++ 方法:
这个方法实际上是调用了一个GUI模态窗口,实现基于 Qt 的 alert 提示。
然后使用JS 引擎相关方法把它包装到JS的全局对象中。
这样,C++ 实现的 alert 方法就被包装到 js 中。在js 全局调用 alert 就可以谈出对话框。
第二个比较复杂,不好用既有代码表述。
尽量简单的来描述下。
基于 GUI 的系统呢,其 UI 部分会有个 EventLoop(真不想用这个词儿……) 或者 MessageLoop 线程来收发消息。毕竟用户操作基本上是异步的,总得响应操作事件,这个不难理解吧。
如果,开启模态窗口后续操作禁止了,那么有几种可能性:
第三个也是锁死界面,但是有缓。
为啥呢,起码 开启的 alert UI 可以自己内部开个消息线程来接替主消息循环接收用户输入响应就好了。
都知道的,消息线程其实就是个有条件退出的死循环。等用户点击确定啊,关闭啊,它就到达退出条件了,然后把主消息循环恢复,主界面又可以响应用户操作了,然后关闭(擦除)自身UI就好了。
这里有个小细节,就是模态窗口阻塞代码的事儿。这不是绝对的(这里说的是浏览器JS实现的模态)。
比如:
BX9015: setTimeout 和 setInteval 在各浏览器中被对话框阻塞的情况不同
细节上来说,这 可能取决于alert内消息循环实现,这个 while(true) 是否处于主代码执行之前,还是另开了线程来异步循环的。
如:
一旦如此实现,可见,在alert 的内部消息循环有条件退出前,主代码会被阻塞。
链接:http://www.zhihu.com/question/20963787/answer/34123046
来源:知乎
著作权归作者所有,转载请联系作者获得授权
- JS BOM api 中 alert 的实现
- GUI 中模态窗口阻塞其他代码运行原理
第一个比较简单。
首先它是目标平台的包装函数,也就是非JS原生 API。
这需要调用JS 引擎的包装方法来作,也就是JS引擎(一般是C++ Lib)会给出一些用来把目标平台业务API(函数)包装为可使用JS语法调用的机制。
比如 Qt C++ 方法:
QScriptValue ScriptBinding::alert(QScriptContext *context, QScriptEngine *interpreter)
{
...
QMessageBox messageBox;
messageBox.information(NULL,
"App Message:",
message,
QMessageBox::Yes, QMessageBox::Yes);
return QScriptValue::UndefinedValue;
}
然后使用JS 引擎相关方法把它包装到JS的全局对象中。
// 获取JS引擎
QScriptEngine engine = new QScriptEngine();
// 获取JS全局环境
globalObject = engine->globalObject();
QScriptValue nativeMathod;
// 引擎包装一个新方法,执行这个方法时候将调用 C++ 的alert函数
nativeMathod = engine->newFunction(ScriptBinding::alert);
// 把这个包装好的alert方法放到JS全局环境中
globalObject.setProperty("alert", nativeMathod, QScriptValue::ReadOnly | QScriptValue::Undeletable);
第二个比较复杂,不好用既有代码表述。
尽量简单的来描述下。
基于 GUI 的系统呢,其 UI 部分会有个 EventLoop(真不想用这个词儿……) 或者 MessageLoop 线程来收发消息。毕竟用户操作基本上是异步的,总得响应操作事件,这个不难理解吧。
如果,开启模态窗口后续操作禁止了,那么有几种可能性:
- 执行线程终止
- 执行线程被 sleep
- 无视MessageLoop(也就是不响应用户操作事件)
第三个也是锁死界面,但是有缓。
为啥呢,起码 开启的 alert UI 可以自己内部开个消息线程来接替主消息循环接收用户输入响应就好了。
都知道的,消息线程其实就是个有条件退出的死循环。等用户点击确定啊,关闭啊,它就到达退出条件了,然后把主消息循环恢复,主界面又可以响应用户操作了,然后关闭(擦除)自身UI就好了。
这里有个小细节,就是模态窗口阻塞代码的事儿。这不是绝对的(这里说的是浏览器JS实现的模态)。
比如:
BX9015: setTimeout 和 setInteval 在各浏览器中被对话框阻塞的情况不同
细节上来说,这 可能取决于alert内消息循环实现,这个 while(true) 是否处于主代码执行之前,还是另开了线程来异步循环的。
如:
主UI代码
....
alert()
内部
while(true){
....
}
主 UI 后续代码