Как исправить состояние гонки между разрешениями Promise для события win.loadFile () и app.on ('browser-window-made') - PullRequest
0 голосов
/ 02 мая 2019

Я работаю над приложением Electron, где один модуль создает BrowserWindow, а другие модули (все они в основном процессе) могут получить доступ к окну после того, как было полностью загружено (включая ситуациигде окно было закрыто в то же время).

Я работаю с Electron 5.0.0 на macOS.

Вот упрощенная версия того, что я придумал, поэтомуfar:

// module mainWindow.js

const { BrowserWindow } = require('electron')
let ready = null

const createWindow = () => {
  console.log('creating window')  
  return new Promise((resolve) => {  
    let win = new BrowserWindow({
      show: false,
    })
    win.on('closed', () => {
      ready = null
    })
    win.loadFile('renderer.html').then(() => {
      win.show()
      resolve(win)
      console.log('window.load resolved')    
    })
    console.log('window id', win.id)        
}

const get = (create) => {
  console.log('get')
  if (ready) {
    console.log('ready')
    return ready
  } else {
    console.log('not ready')
    if (create) {
      console.log('creating')
      ready = createWindow()
      return ready
    } else {
      console.log('rejecting')
      return Promise.reject()
    }
  }
}

exports.get = get


// some other module

const win = require('mainWindow.js')
win.get(true).then((win) => { /* ... */ })


// yet another module

const { app } = require('electron')
const win = require('mainWindow.js')
app.on('browser-window-created', () => {
  console.log('app.browser-window-created')
  win.get(false).then((win) => {
    log('got it')
    // ...
  }, () => {
    log('there is no window')
  })
})

На мой взгляд, createWindow() должен возвращать неразрешенное обещание (которое затем сохраняется в ready) до асинхронного создания окна.Но моя консоль гласит:

get
not ready
creating
creating window
app.browser-window-created
get
not ready
rejecting
window id 1
there is no window
window.load resolved

Есть ли способ исправить это?

Ответы [ 2 ]

1 голос
/ 02 мая 2019

Похоже, проблема в том, что событие запускается синхронно, поэтому оно запускается до завершения выполнения функции, а ready = еще не запущено.Чтобы решить эту проблему, вы должны отложить создание окна:

  return new Promise((resolve, reject) => {
   setTimeout(() => {
     //...
   });
  });

Вы также можете отложить это использование другого обещания при назначении на ready внутри get:

  ready = Promise.resolve().then(createWindow);

В качестве альтернативыВы можете переназначить ready перед созданием окна, для этого вы должны выставить resolve из обратного вызова:

  let resolve;
  ready = new Promise(it => resolve = it);

  // create window ...
  // somewhen ...
  resolve(win);
0 голосов
/ 02 мая 2019

Ваша проблема в том, что let win = new BrowserWindow немедленно запускает событие 'browser-window-created', поэтому в его обратном вызове вы не найдете ожидающих обещаний.

Поэтому я предлагаю вам реструктурировать код.

Например, app.on('browser-window-created') можно использовать для получения созданного BrowserWindow. При добавлении слушателя к 'did-finish-load' веб-содержимого BrowserWindow вы просто получаете точно тот же самый обратный вызов, что и при возвращении Promise ( loadFile разрешает для этого события)

app.on('browser-window-created', (event, window) => {
  console.log('app.browser-window-created')
  window.webContents.on('did-finish-load', () => {
    console.log('got it')
    // ...
  })
  window.webContents.on('did-fail-load', () => {
    console.log('there is no window')
  })
})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...