electron 在具有Promise的节点中Jquery触发过快,all

wljmcqd8  于 2022-12-16  发布在  Electron
关注(0)|答案(1)|浏览(122)

我在Electron和Node中有一些异步代码,每个循环都在Jquery中运行,然后在完成后做出React:

$(async() => {
  if (await window.electronAPI.delete_items(project.name)) {
    var _count = 0;
    $.each(project.items, function(i, item) {
      var promises = item.subitems.map(async function(subitem) {
        return await window.electronAPI.update_item(subitem);
      });

      Promise.all(promises).then(function() {
        _count++;
        if (_count >= project.items.length) {
          $("#overlay").css("display", "none");
          console.log("Done");
        }
      });
    });
  }
});

不过,所有这些都很好用:

$( "#overlay" ).css( "display", "none" );

立即运行,而:

console.log( "Done" );

在更新所有项目后正确运行。
我需要做些什么来防止JQuery过早运行?
谢谢:)
编辑以添加完整代码:

index.js
--------------------------------------

app.whenReady().then( () => {

  ...

    ipcMain.handle( "delete_all_cached_images", delete_all_cached_images );
    ipcMain.handle( "update_cached_image", update_cached_image );

    /* Create the window */
    createWindow();

    app.on( "activate", () => {
        
        /* Fix MacOS multi window bug */
        if( BrowserWindow.getAllWindows().length === 0 ) createWindow();
    } );
} );

async function update_cached_image( e, project_name, image_type, image_size, image_name, image_data ) {

    /* Create a new blank image */
    let image = new Jimp( image_size, image_size, function ( err, image ) {
        
        if( err )
            return false;

        /* Map the pixels correct */
        var _image_data = Array.from( { length: image_size }, () => Array.from( { length: image_size }, () => undefined ) );

        for( var row_sel = 0; row_sel < image_size; row_sel++ )
            for( var col_sel = 0; col_sel < image_size; col_sel++ )
                _image_data[ col_sel ][ row_sel ]  = image_data.data[ row_sel ][ col_sel ];

        /* Loop through each pixel to add to the image */
        _image_data.forEach( ( row, y ) => {

            row.forEach( ( colour, x ) => {

                /* If we have a transparent pixel, don't add it to the image */
                if( ( colour == "" ) || ( colour == null ) )
                    image.setPixelColor( Jimp.rgbaToInt( 0, 0, 0, 0 ), parseInt( x ), parseInt( y ) );
                else 
                    image.setPixelColor( Jimp.cssColorToHex( "#" + colour ), parseInt( x ), parseInt( y ) );
            } );
        } );

        /* Resize to a nice large size */
        image.resize( 512, 512 , Jimp.RESIZE_NEAREST_NEIGHBOR );

        /* Save the image to project directory */
        image.write( path.join(  __dirname, "projects", project_name, "cache", image_type, image_name + ".png" ), ( err ) => {
        
            if( err )
                return false;
        } );
    } );

    return true;
}

preload.js
--------------------------------------
const { contextBridge, ipcRenderer } = require( "electron" );

contextBridge.exposeInMainWorld( "electronAPI", {

    ...

    delete_all_cached_images: ( project_name ) => ipcRenderer.invoke( "delete_all_cached_images", project_name ),
    update_cached_image: ( project_name, image_type, image_size, image_name, image_data ) => ipcRenderer.invoke( "update_cached_image", project_name, image_type, image_size, image_name, image_data )
} );

renderer.js
--------------------------------------
function update_cached_images() {

    $( async () => {

        /* First delete all old cached images */
        if( await window.electronAPI.delete_all_cached_images( project.name ) ) {

            var ti = 0;
            Promise.all( project.textures.map( g_texture => {
                
                return Promise.all( g_texture.textures.map( texture => {

                    return window.electronAPI.update_cached_image( project.name, "textures", 8, ( g_texture.name + "_" + ti++ ), texture );
                } ) );
            } ) ).then( () => {
                
                $("#overlay").css("display", "none");
                console.log("Done");
            } ).catch(err => {

                console.log(err);
                // add something to handle/process errors here
            } );
            
        } else {

            show_error( "Error caching project textures." );
        }
    } );
}
pxq42qpu

pxq42qpu1#

您可以去掉计数器,并在调用$( "#overlay" ).css( "display", "none" );之前适当地等待所有承诺完成,如下所示:

$(async () => {
    if (await window.electronAPI.delete_items(project.name)) {
        Promise.all(project.items.map(item => {
            return Promise.all(item.subitems.map(subitem => {
                return window.electronAPI.update_item(subitem);
            }));
        })).then(() => {
            $("#overlay").css("display", "none");
            console.log("Done");
        }).catch(err => {
            console.log(err);
            // add something to handle/process errors here
        });
    }
});

当然,这是假设window.electronAPI.update_item(subitem);返回一个只有在完成时才能正确解析的承诺,如果它没有返回一个承诺,或者承诺只有在完成时才能解析,那么我们也必须修正这个问题。
以下是update_cached_image()的修复版本,它返回一个承诺,该承诺在完成时解析:

function update_cached_image(e, project_name, image_type, image_size, image_name, image_data) {
    return new Promise((resolve, reject) => {
        /* Create a new blank image */
        new Jimp(image_size, image_size, function(err, image) {
            if (err) {
                reject(err);
                return;
            }

            /* Map the pixels correct */
            var _image_data = Array.from({ length: image_size }, () => Array.from({ length: image_size }, () => undefined));

            for (var row_sel = 0; row_sel < image_size; row_sel++)
                for (var col_sel = 0; col_sel < image_size; col_sel++)
                    _image_data[col_sel][row_sel] = image_data.data[row_sel][col_sel];

            /* Loop through each pixel to add to the image */
            _image_data.forEach((row, y) => {

                row.forEach((colour, x) => {

                    /* If we have a transparent pixel, don't add it to the image */
                    if ((colour == "") || (colour == null))
                        image.setPixelColor(Jimp.rgbaToInt(0, 0, 0, 0), parseInt(x), parseInt(y));
                    else
                        image.setPixelColor(Jimp.cssColorToHex("#" + colour), parseInt(x), parseInt(y));
                });
            });

            /* Resize to a nice large size */
            image.resize(512, 512, Jimp.RESIZE_NEAREST_NEIGHBOR);

            /* Save the image to project directory */
            image.write(path.join(__dirname, "projects", project_name, "cache", image_type, image_name + ".png"), (err) => {
                if (err) {
                    reject(err);
                    return;
                } else {
                    resolve(image);
                }
            });
        });
    });
}

相关问题