首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >NodeJS和电子请求-承诺后端冻结CSS动画在前端

NodeJS和电子请求-承诺后端冻结CSS动画在前端
EN

Stack Overflow用户
提问于 2018-01-24 19:52:07
回答 1查看 1.5K关注 0票数 9

注意:附加在原始问题末尾的附加信息,如编辑#1__,详细说明后端的request-promise是如何导致UI冻结的。请记住,一个纯CSS动画暂时挂起,您可能只需跳过编辑(或阅读所有的完整性)。

安装程序

我正在使用电子开发一个桌面网络应用程序。

有一次,用户需要输入并提交一些数据。当他们单击"submit“时,我使用JS显示此css加载动画 (右下角加载器),并将数据异步发送到后端.

- HTML -

代码语言:javascript
复制
<button id="submitBtn" type="submit" disabled="true">Go!</button>

<div class="submit-loader">
    <div class="loader _hide"></div>
</div>

- JS -

代码语言:javascript
复制
form.addEventListener('submit', function(e) {
    e.preventDefault();

    loader.classList.remove('_hide');

    setTimeout(function() {
        ipcRenderer.send('credentials:submit', credentials);
    }, 0)
});

其中._hide是简单的

代码语言:javascript
复制
._hide {
    visibility: hidden;
}

其中ipcRenderer.send()是一个异步方法,没有其他设置的选项。

问题

通常,0ms延迟足以允许在阻塞事件发生之前更改DOM。但不是在这里。无论是否使用setTimeout(),仍然存在延迟。

所以,再加点时间.

代码语言:javascript
复制
loader.classList.remove('_hide');

setTimeout(function() {
    ipcRenderer.send('credentials:submit', credentials);
}, 100);

太棒了!装载机在提交时立即显示!但是..。在100毫秒后,动画停止在它的轨道上,大约500毫秒左右,然后回到学习。

这种不工作的->不工作->工作模式,不管延迟长度如何。一旦ipcRenderer开始做一些事情,一切就会停止。

所以..。为什么!?

这是我第一次看到这种行为。我对HTML/CSS/JS相当熟悉,但我承认我对NodeJS和电子很陌生。为什么我的纯CSS动画会被ipcRenderer停止,我能做些什么来补救这个问题呢?

编辑#1 -附加信息

在后端(NodeJS)中,我使用请求-承诺调用外部API。当后端接收到ipcRenderer消息时就会发生这种情况。

代码语言:javascript
复制
var rp = require('request-promise');

ipcMain.on('credentials:submit', function(e, credentials) {    

    var options = {
        headers : {
            ... api-key...
        },
        json: true,
        url : url,
        method : 'GET'
    };

    return rp(options).then(function(data) {
        ... send response to callback...
    }).catch(function(err) {
        ... send error to callback...
    });

}

buggy冻结行为只发生在第一个API调用上。连续的API调用(即在不重新启动NodeJS后端的情况下刷新桌面应用程序),不要导致挂起。即使我调用了不同的API方法,也没有任何问题。

现在,我已经实现了以下恶意解决方案:

首先,用BrowserWindow初始化第一个show:false.

代码语言:javascript
复制
window = new BrowserWindow({
    show: false
});

当窗口准备好后,发送一个ping到外部API,并且只在成功响应后显示该窗口.

代码语言:javascript
复制
window.on('ready-to-show', function() {
    apiWrapper.ping(function(response) {
        if(response.error) {
            app.quit();
        }else {
            window.show(true);
        }
    });
});

这一额外步骤意味着窗口出现前大约有500 is的延迟,但是所有连续的API调用(无论是.ping()还是其他调用)都不再阻止UI。我们快到回调地狱的边缘了,但这还不算太糟。

所以..。这是一个request-promise问题(据我所知,这是异步的)。不知道为什么这种行为只出现在first call上,所以如果您知道,请随时通知我!否则,这个讨厌的小东西现在就得做了。

(注意:我是唯一一个使用这个桌面应用程序的人,所以我不太担心显示"ping失败“消息。对于商业版本,我会提醒用户API调用失败。)

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-01-24 23:01:46

值得检查请求-承诺内部设置如何加载模块。读取它时,似乎在调用请求时存在某种延迟加载(https://github.com/request/request-promise/blob/master/lib/rp.js#L10-L12)。快速试验

代码语言:javascript
复制
const convertHrtime = require('convert-hrtime');

const a = require('request-promise');

const start = process.hrtime();
a({uri: 'https://requestb.in/17on4me1'});
const end = process.hrtime(start);
console.log(convertHrtime(end));

const start2 = process.hrtime();
a({uri: 'https://requestb.in/17on4me1'});
const end2 = process.hrtime(start2);
console.log(convertHrtime(end2));

返回值如下所示:

代码语言:javascript
复制
{ seconds: 0.00421092,
  milliseconds: 4.21092,
  nanoseconds: 4210920 }
{ seconds: 0.000511664,
  milliseconds: 0.511664,
  nanoseconds: 511664 }

第一次通话的时间显然比随后的要长。(当然,数量可能有所不同,我是在相对较快的cpu上运行的)如果模块加载是第一次调用的主要成本,那么它会阻塞主进程直到加载模块(因为node.js require解析是同步的)。

我不能说这是具体的原因,但值得一查。正如注释中所建议的,尝试其他库或裸内部模块(如电子的net)来排除。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48430578

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档