首页 > 解决方案 > JS/Electron 逐项添加

问题描述

抱歉,如果我不能很好地解释自己,我有一个函数(下面的代码)可以解析一个 json 并创建一个包含 1550 个项目的网格,如何将它们一个一个添加而不是全部添加在一起?因为这种方式效果很好,但加载 1500 需要时间。

function additem () {
  fs.readFile(path.join(__dirname, 'list.json'), 'utf8', (err, data) => {
    if (err) {
      alert('Could not read file.\n\nDetails:\n' + err.message)
      return
    }
    let json = JSON.parse(data)
    for (let i in json) {
      mainWindow.webContents.executeJavaScript(`
        document.getElementById("grid").innerHTML += '<a href="${json[i].desc}"><div class="cell" id=${i}>${json[i].title}</div> </a>'
      `)

    }
  })
}

在下面的代码中,我创建了窗口,显示启动画面,然后显示主窗口。然后我在应用程序上调用该功能准备就绪

function puziale () {
    splash = new BrowserWindow({width: 200, height: 200, transparent: true, frame: false, alwaysOnTop: true});
    (async ()=>{  
        createWindow(); 
        splash.loadFile('splash.html');  
        await sleep(2000);  
        splash.destroy();
        mainWindow.show()
        
      })();
 
    
    
}

app.on('ready', puziale);

谢谢你的帮助

标签: javascripthtmlcssnode.jselectron

解决方案


你的问题很好。它是异步编程的基础。您应该将函数替换为:

选项 A)

如果项目的顺序无关紧要

async function loop_iteration(json, i) {
    mainWindow.webContents.executeJavaScript(`
        document.getElementById("grid").innerHTML += '<a href="${json[i].desc}"><div class="cell" id=${i}>${json[i].title}</div> </a>'
      `)
}

function additem () {
  fs.readFile(path.join(__dirname, 'list.json'), 'utf8', (err, data) => {
    if (err) {
      alert('Could not read file.\n\nDetails:\n' + err.message)
      return
    }
    let json = JSON.parse(data)
    for (let i in json) {
        loop_iteration(json, i);
    }
  })
}

这使得每个循环迭代异步 - 因此每个循环迭代都在不等待前一个循环迭代的情况下执行。

选项 B)

如果项目的顺序确实很重要。

页面不会冻结,但所有迭代都会立即执行。

async function loop(json) {
    for (let i in json) {
        mainWindow.webContents.executeJavaScript(`
        document.getElementById("grid").innerHTML += '<a href="${json[i].desc}"><div class="cell" id=${i}>${json[i].title}</div> </a>'
      `)
    }
}

function additem() {
    fs.readFile(path.join(__dirname, 'list.json'), 'utf8', (err, data) => {
        if (err) {
            alert('Could not read file.\n\nDetails:\n' + err.message)
            return
        }
        let json = JSON.parse(data)
        loop(json);
    })
}

这使得整个循环异步,因此每个循环迭代都会等待之前的迭代,因此用户不会遇到任何卡顿。但它会一次执行所有迭代...... :(

为了两全其美,您可以考虑这样做:

选项 c)

和你想象的完全一样。

async function loop_iteration(json, i) {
    mainWindow.webContents.executeJavaScript(`document.getElementById("grid").innerHTML += '<a href="${json[i].desc}"><div class="cell" id=${i}>${json[i].title}</div> </a>'`)
}

async function loop(json) {
    for (let i in json) {
        await loop_iteration(json, i);
    }
}

function additem() {
    fs.readFile(path.join(__dirname, 'list.json'), 'utf8', (err, data) => {
        if (err) {
            alert('Could not read file.\n\nDetails:\n' + err.message)
            return
        }
        let json = JSON.parse(data)
        loop(json);
    })
}

在这段代码中,我告诉浏览器“不要等待 for 循环结束,而是每次迭代都在最后一次结束后才执行。

选项 D)

加载具有异步优势的 JSON,并且只执行和呈现页面一次。

async function loop_iteration(json, i, arr) {
    arr.push(`<a href="${json[i].desc}"><div class="cell" id=${i}>${json[i].title}</div> </a>`)
}

async function loop(json) {
    const arr = []
    for (let i in json) {
        await loop_iteration(json, i, arr);
    }
    mainWindow.webContents.executeJavaScript(`document.getElementById("grid").innerHTML += '${arr.join('')}'`)
}


function additem() {
    fs.readFile(path.join(__dirname, 'list.json'), 'utf8', (err, data) => {
        if (err) {
            alert('Could not read file.\n\nDetails:\n' + err.message)
            return
        }
        let json = JSON.parse(data)
        loop(json);
    })
}

推荐阅读