2013-03-15 22 views
2

JSFiddle CodeJQUERY鏈接使用進程和管道不是爲我工作

管道和鏈接是新的我......

我有收到這個小腳本工作的問題。我有一組需要用AJAX同步觸發的URL。我需要等待每個url的成功響應(有些可能會延遲,因爲它們將運行大型SQL查詢和構建報告),然後再管道到下一次迭代。如果它沒有獲得成功,那麼整個過程必須停止。

我覺得我很接近很多小動作,但是你會發現它不能正常工作。也許你們中的一位大師可以幫助我解決這個問題?

//counter 
var i = 0; 

//array of local urls that I need to trigger one after another 
var arrValues = [ 
    "http://fiddle.jshell.net/", 
    "http://fiddle.jshell.net/", 
    "http://fiddle.jshell.net/"]; 

//the step i need to repeat until done 
var step = (function() { 

    //expect to see this alert called for each iteration (only happens once?) 
    alert(arrValues[i]+i); 

    var url = arrValues[i]; 
    var model = {}; 

    model.process = function() { 
     log('Starting: ' + url + i); 

     return $.ajax(url) 
      .done(function (jqXHR, textStatus, errorThrown) { 
      log(textStatus + ' ' + url + i + ' Done'); 
     }) 
      .fail(function (jqXHR, textStatus, errorThrown) { 
      log(textStatus + ' Failed'); 
     }); 
    }; 

    return model; 
}()); 

//just outputting to the div here 
function log(message) { 
    $("#output").append($("<div></div>").text(message)); 
} 

//start the process 
log("Starting To Build Report"); 

//iterate through the array 
$.each(arrValues, function (intIndex, objValue) { 

    // I need to wait for success before starting the next step or fail and throw 
    // the errors below - you will see this does not work now and never gets to the 
    // .done or .fail or .always 

    step.process().pipe(function() { 
     i++; 
     step.process(); 
    }); 

}).done(function() { 
    log("The process completed successfully"); 
}) 
    .fail(function() { 
    log("One of the steps failed"); 
}) 
    .always(function() { 
    log("End of process"); 
}); 

回答

1

你快到了,但細節都很重要。訣竅是:

  • 修改step是一個函數(而不是一個對象),它返回一個函數,它本身返回一個可觀察到的物體(即一個jqXHR承諾。)
  • 以允許step接受一個作爲參數的增量整數i;這避免了在外部範圍保持運行i
  • 打造.then()鏈各then()以作爲其參數由step()
  • 返回的功能與解決無極播種.then()鏈得到它開始
  • 將最後的.done(),.fail(),.always()附加到then()鏈的末尾。

注意:從jQuery 1.8開始,.pipe()已被棄用,轉而使用修訂版.then()

下面的代碼:

var arrValues = [ 
    "http://fiddle.jshell.net/", 
    "http://fiddle.jshell.net/", 
    "http://fiddle.jshell.net/" 
]; 

function step(i) { 
    return function() { 
     var url = arrValues[i]; 
     log('Starting: ' + url + i); 
     return $.ajax(url).done(function(data, textStatus, jqXHR) { 
      log(textStatus + ' ' + url + i + ' Done'); 
     }).fail(function(jqXHR, textStatus, errorThrown) { 
      log(textStatus + ' ' + url + i + ' Failed'); 
     }); 
    } 
}; 

function log(message) { 
    $("#output").append($("<div/>").text(message)); 
} 

log("Starting To Build Report"); 

var p = $.Deferred().resolve().promise(); 
$.each(arrValues, function(i, url) { 
    p = p.then(step(i)); 
}); 
p.done(function() { 
    log("The process completed successfully"); 
}).fail(function() { 
    log("One of the steps failed"); 
}).always(function() { 
    log("End of process"); 
}); 

Updated fiddle