Wait for callback before continue for loop

后端 未结 2 624
情话喂你
情话喂你 2020-12-02 07:59

I\'ve a for-loop I\'m looping through.

I want to make a custom modal and wait for a response before continue it.

How can I achieve this? I know I\'ve to wait

相关标签:
2条回答
  • 2020-12-02 08:26

    Assuming this is your array

    var list = ['one','two','three'];
    

    You can try using this loop / callback approach

    var x = 0;
    var loopArray = function(arr) {
        customAlert(arr[x],function(){
            // set x to next item
            x++;
    
            // any more items in array? continue loop
            if(x < arr.length) {
                loopArray(arr);   
            }
        }); 
    }
    
    function customAlert(msg,callback) {
        // code to show your custom alert
        // in this case its just a console log
        console.log(msg);
    
        // do callback when ready
        callback();
    }
    

    Usage:

    // start 'loop'
    loopArray(list);
    

    JSFiddle here: http://jsfiddle.net/D9AXp/

    0 讨论(0)
  • 2020-12-02 08:28

    MaggiQall, I know you have an answer but I have a flexible solution that may be of interest to you or maybe to someone else.

    The solution depends on jQuery (1.7+) and jQuery UI's dialog, but is implemented as a custom method of the Array prototype, not as a jQuery plugin.

    Here's the Array method :

    Array.prototype.runDialogSequence = function(dialogCallback, startIndex, endIndex){
        startIndex = Math.max(0, startIndex || 0);
        endIndex = Math.min(this.length - 1, endIndex || this.length - 1);
        var sequenceIndex = 0,
            arr = this,
            dfrd = $.Deferred().resolve(startIndex);
        function makeCloseFn(seqData){
            return function(event, ui){
                if(seqData.continue_) { seqData.dfrd.resolve(seqData.arrayIndex+1, seqData); } //continue dialog sequence
                else { seqData.dfrd.reject(seqData.arrayIndex, seqData); } //break dialog sequence
            }
        }
        $.each(this, function(i){
            if(i < startIndex || i > endIndex) { return true; }//continue
            dfrd = dfrd.then(function(arrayIndex){
                var seqData = {
                    dfrd: $.Deferred(),
                    arrayIndex: arrayIndex,
                    sequenceIndex: ++sequenceIndex,
                    length: 1 + endIndex - startIndex,
                    item: arr[arrayIndex],
                    continue_: false
                };
                dialogCallback(seqData).on("dialogclose", makeCloseFn(seqData));
                return seqData.dfrd.promise();
            });
        });
        return dfrd.promise();
    }
    

    Array.runDialogSequence() relies on :

    • A dialog template in the document's body, fit to be populated with text/values.
    • an array of similar items (typically javascript objects) containing the data required to populate the dialog, in sequence.
    • passing, as the first argument, a correctly constructed "openDialog" function.

    Here's a sample "openDialog" function with explanatory comments :

    function openDialog(seqData){
        /*
        seqData is an object with the following properties:
            dfrd: A Deferred object associated with the current dialog. Normally resolved by Array.runDialogSequence() to run through the sequence or rejected to break it, but can be resolved/rejected here to force the dialog sequence to continue/break. If resolved, then pass (seqData.arrayIndex+1, seqData), or custom values. If rejected, typically pass (seqData.arrayIndex, seqData).
            arrayIndex: The current array index.
            sequenceIndex: The current index within the sequence. Normally the same as arrayIndex but Differs when a non-zero startIndex is specified.
            length: The full length of the dialog sequence.
            item: The current item from the array.
            continue_: (false) Set to true to allow the sequence to continue.
        */
        var item = seqData.item;
        var $d = $("#d");
        $d.dialog({
            title: 'Dialog (' + seqData.sequenceIndex + ' of ' + seqData.length + ')',
            modal: true,
            buttons: {
                "Continue": function(){
                    seqData.continue_ = true;//set to true before closing to go to next dialog.
                    $(this).dialog("close");
                },
                "Cancel": function(){
                    $(this).dialog('close');//closing with seqData.continue_ set to its default value false will break the dialog sequence.
                }
            }
        }).find("#message").text(item);//Typically you will do a lot more here to populate the dialog with item data.
        return $d;//openDialog() must return a dialog container, jQuery-wrapped.
    }
    

    Array.runDialogSequence() returns a jQuery promise, allowing custom actions to be performed when the dialog sequence completes (done function) or is broken in mid-sequence (fail function).

    Here are a couple of sample calls :

    //Simplest possible
    $("#myButton1").click(function(){
        myArray.runDialogSequence(openDialog);
    });
    
    //Call with custom startIndex and endIndex, and chanined `.then()` to provide custom actions on break/completion.
    $("#myButton2").click(function(){
        myArray.runDialogSequence(openDialog, 1, 3).then(function(i, seqData){
            alert('All dialogs complete - last item = "' + seqData.item + '"');
        }, function(i, seqData){
            alert('Dialog sequence was broken at item ' + i + ' "' + seqData.item + '"');
        });
    });
    

    DEMO

    This is as close to a generalized solution as my imagination allows.

    0 讨论(0)
提交回复
热议问题