我有一个用Electron构建的音乐播放器。
我正在进行一些我没想到的性能/进程阻塞。我正在尝试为繁重的IO操作做一些后台进程。 (确定歌曲持续时间和专辑封面)
我这样做是通过electron.remote模块调用方法。 我注意到应用程序没有以某种方式异步地执行这些操作。
我一直在运行性能工具来检查并看到点击处理程序耗费了大量时间。
深入挖掘我发现ipcRenderer.sendSync
被调用。
Electron Docs中有关于sendSync
阻止性质的警告。但是,我自己的代码不会调用它。所以我怀疑代码中的远程模块或其他东西会导致调用sendSync
。
整个应用代码都在Github上,但here is an example of electron.remote usage。
要点是这样的:
import {remote} from 'electron'
const fs = remote.require('fs')
const mm = remote.require('musicmetadata')
// read song file, IO
function readMetadata (filePath) {
return new Promise(function (resolve, reject) {
const stream = fs.createReadStream(filePath)
mm(stream, {duration: true}, function (err, metadata) {
// ...
})
})
}
// get metadata for an array of songs
async function refreshSongsDuration (songs) {
const songsMetadata = await Promise.all(songs.map((song) => readMetadata(song.filePath)))
return songs.map((song, index) => {
song.duration = songsMetadata[index].duration
return song
})
}
然后在点击处理程序中我会有这样的事情:
playArtist (artistID) {
const songs = this.library.getArtistSongs(artistID)
this.playlist.setSongs(songs)
musicPlayer.play()
const shouldGetDuration = songs.some((song) => song.duration === 0)
// This is expected to be asynchronous and non blocking.
if (shouldGetDuration) {
mediaLibrary.refreshSongsDuration(songs)
.then((updatedSongs) => {
this.playlist.set('songs', updatedSongs)
})
}
}
所以,我想这里的一个简单问题是,我做错了什么导致这些阻塞过程?
答案 0 :(得分:0)
https://github.com/electron/electron/blob/master/docs/api/remote.md#remote-objects
远程模块返回的每个对象(包括函数)表示主进程中的对象(我们将其称为远程对象或远程函数)。当您调用远程对象的方法,调用远程函数或使用远程构造函数(函数)创建新对象时,您实际上是在发送同步进程间消息。
每个远程模块本质上都是同步的。