-2

I have a function that pushes promises from other functions that are also resolving arrays of promises. I was just wondering if this code is OK.

Here is the main function

    /// <summary>Process the validation results (invalid IDR records will have the iop=4)</summary>
this.processValidationResults = function ()
{
    var promises = [];
    var count = (self.idrValidationList.length - 1);

    $.each(self.idrValidationList, function (index, idrValidationItem)
    {
        _onProgress(self.utils.formatCounterMessage(index, count, 'Processing Validation Items'));

        if (idrValidationItem.is_valid = 0)
        {
            //there is a problem with this IDR record
            //update the idr_insp table
            promises.push(self.updateInvalidEntity(self.configEntities.idr_insp, idrValidationItem.idr_insp_id));
            promises.push(self.updateInvalidChildren(self.configEntities.idr_insp, idrValidationItem.idr_insp_id));
        }
        else
        {
            //push resolved promise
            promise.push($.when());
        }     
    });

    return ($.when.apply($, promises));
}

Here are the functions that are called by the above function

/// <summary>Update the invalid record, sets the IOP field to 4 [Cannot sync due to issue]</summary>
/// <param name="entity" type="Object">GLobal entity definiton </param>
/// <param name="tabletId" type="Int">Primary Key on the tablet to change</param>
this.updateInvalidEnity = function (entity, tabletId)
{
    //update the record with the new ID and IOP status
    var updateSql = 'UPDATE ' + entity.name + ' SET  iop=? WHERE ' + entity.key_field + '=?';

    //update the record
    return (self.db.executeSql(updateSql, [4, tabletId]));
}

/// <summary>Update the invalid child records, sets the IOP field to 4 [Cannot sync due to issue]</summary>
/// <param name="entity" type="Object">GLobal entity definiton </param>
/// <param name="keyId" type="Int">Foreign Key on the tablet to change</param>
this.updateInvalidChildren= function (parentEntity, keyId)
{
    var promises = [];
    $.each(parentEntity.child_entities, function (index, child)
    {
        var def = new $.Deferred();
        var updateSql = 'UPDATE ' + child.child_name + ' SET  iop=? WHERE ' + child.key_field + '=?';

        promises.push(self.db.executeSql(updateSql, [4, keyId]));
    });

    return ($.when.apply($, promises));
}

And all of the above methods are pushing the deferred below.

/* Executes the sql statement with the parameters provided and returns a deffered jquery object */
this.executeSql = function (sql, params)
{
    params = params || [];

    var def = new $.Deferred();

    self.db.transaction(function (tx)
    {
        tx.executeSql(sql, params, function (itx, results)// On Success
        {
            // Resolve with the results and the transaction.
            def.resolve(itx, results);
        },
        function (etx, err)// On Error
        {
            // Reject with the error and the transaction.
            def.reject(etx, err);
        });
    });

    return (def.promise());
}

Is this chain sound? Have not tested yet but I think it is OK. Just want some other eyes on this before I continue...

gdex
  • 465
  • 1
  • 4
  • 10
  • 3
    Isn't this a bit too much asked, to just check whether someone could maybe find a problem, if you not even tested it yourself?! Why couldn't you just find out whether this is working or not on your own? – Martin Feb 14 '14 at 15:37
  • 1
    @Martin, Because there is no data loaded in the local tablet database currently in development. I am tasked with writing data sync code with no data. Just asking a question. I don't think the question is that hard for anyone that understands deferreds. So provide an answer or keep your pointless comment to yourself... – gdex Feb 14 '14 at 15:45
  • Pretty aggressive ... – Martin Feb 14 '14 at 15:48
  • Just dont have time for reading why I should not have posted a question... Sorry – gdex Feb 14 '14 at 15:53

1 Answers1

1

This should really be in Code Review, not SO, but here goes ...

A few observations :

  • As written, the progress message in .processValidationResults(), is an indication of requests made, not responses received. It will therefore jump straight to "count of count".

  • In .processValidationResults(), else { promise.push($.when()); } is unnecessary.

  • In .updateInvalidChildren(), var def = $.Deferred() is unnecessary.

  • jQuery Deferred's resolve and reject methods are "detachable". In this.executeSql(), as you want simply to pass the parameters through, you can simplify the tx.executeSql(...) call to tx.executeSql(sql, params, def.resolve, def.reject).

  • Assuming self.db.executeSql performs AJAX (and that tx.executeSql() does not somehow queue the requests), the code has the potential to hit the server hard with simultaneous requests. Make sure it can handle the number of simultaneous requests that this code will generate. Otherwise, take measures to cause the requests to be made sequentially.

Community
  • 1
  • 1
Beetroot-Beetroot
  • 18,022
  • 3
  • 37
  • 44
  • Thanks for providing your input, I will post in Code Review for now on. In your second bullet, I guess your are saying there is no need to push an empty deferred? So if there is nothing in the array the $.when.apply will return a resolved promise? The executeSql is part of an aync API for SQLite so it is not making a server request just updating a local SQLite DB on the device, so I think I am ok there. Thanks Again for your comments – gdex Feb 16 '14 at 20:55
  • `$.when()` and `$.when.apply($, [])` are identical statements. Your code already (correctly) assumes that `$.when()` returns a resolved promise. It is therefore totally safe to assume that `$.when.apply($, [])` will also return a resolved promise. Proof here: http://jsfiddle.net/SWU8D/ . On the other point, I'm not sure you can ignore the possibility of SQL query overload. Maybe SQLite DB will be OK with multiple rapid-fire queries, maybe not - I don't know. Make sure your test regime gives stress enough for your satisfaction. – Beetroot-Beetroot Feb 17 '14 at 02:23
  • Thanks again! The unit tests will definitely hit the SQLite plugin hard. The current DB design has a small amount (max of 5) related child entities for any given parent entity. We are not anticipating a tremendous amount of updating in this particular part of the sync, but then again it will also depend on how often the end user syncs data, so your point is valid. – gdex Feb 17 '14 at 15:57