2016-10-14 2 views
1

У меня проблема с progressbar. Я хочу, чтобы progressbar изменился после загрузки каждой следующей функции. Это мой код:jQuery, когда(). Done() на нескольких объектах

var tick=1; 
var count=10; 
function example(){ 
    $('#progress div').css('width',(tick*count)+'%'); 
    tick++; 
} 
$.when($.getJSON("data1.json",function(_a){data1=_a;})).done(function(){ 
    example(); 
    $.when(someLoadFunction).done(function(){ 
    example(); 
    $.when(someLoadFunction2).done(function(){ 
     example(); 
     //7 more... 
    }); 
    }); 
}); 

как упростить сценарий, так что он может быть легко расширен в будущем.

+0

Первое упрощение, чтобы не использовать '$ .when' там, потому что в любом случае вы pssing к нему только один обещание каждый раз так: eg: '$ .when (someLoadFunction) .done (function() {...});' такое же, как 'someLoadFunction(). done (function() {...});'. Теперь вы можете запустить все эти ракеты в паралле, а не за другим? –

ответ

2

Создайте массив функций для вызова, а затем выполните эти функции. Не пользователь jQuery, поэтому могут быть более эффективные способы сделать это, но, по крайней мере, это достаточно удобно. Или как @A. Вольф предлагает ... Используйте цепочку.

N.B. Если вы хотите использовать другой обратный вызов для каждой функции, вместо этого передайте литерал объекта в функцию с функцией/обратным вызовом (в этом случае не требуется параметр обратного вызова).

$.when($.getJSON("data1.json", function(_a) { 
    data1 = _a; 
})).done(function() { 
    var functionArr = []; //array of functions 
    loopWhen(functionArr, example()); 
}); 


function loopWhen(functionArr, callback) { 
    (var i = 0; i < functionArr.length; i++) { 
    $.when(functionArr[i]).done() { 
     callback(); 
    }; 
    }; 
}; 
+0

Совсем хорошо @ A.Wolff :-) Если честно, мне не нравится это решение ... Это слишком грязно для меня. –

2

Вы можете использовать .queue(), .promise(), .then(). Сохранять функции в массиве, вызывать следующую функцию в массиве в последовательном порядке, когда обещают текущую функцию. Возвращает объект обещание JQuery из и использовать example в качестве параметра функции в .then()

var tick = 0; 
 
var count = 10; 
 
var url = "https://gist.githubusercontent.com/" 
 
      + "guest271314/23e61e522a14d45a35e1/" 
 
      + "raw/a5ac6cffdc1ffab39f9db425844721b528751654/a.json"; 
 
// handle errors 
 
function err(e) { 
 
    console.log(e) 
 
} 
 

 
function example(data) { 
 
    // do stuff 
 
    console.log(data); 
 
    $("#result").append(data + "<br><br>"); 
 
    // return `.promise()` 
 
    return $("#progress div") 
 
     .css("width", (++tick * count) + "%") 
 
     .promise() 
 
} 
 

 
function progress(fn, next) { 
 
    return fn().then(example).then(next).fail(err) 
 
} 
 
// e.g., `someLoadFunction`, `someLoadFunction2`.. 
 
function someFunction() { 
 
    return $.Deferred(function(dfd) { 
 
    return dfd.resolve(tick) 
 
    }) 
 
} 
 
// e.g., `$.getJSON()`, `someLoadFunction`, `someLoadFunction2`.. 
 
var arr = [ 
 
    function() {return $.getJSON(url)} 
 
    , someFunction, someFunction, someFunction // `someLoadFunction2`.. 
 
    , someFunction, someFunction, someFunction // `someLoadFunction5`.. 
 
    , someFunction, someFunction, someFunction // `someLoadFunction8`.. 
 
]; 
 

 
$({}).queue("progress", $.map(arr, function(deferred) { 
 
    return $.proxy(progress, null, deferred) 
 
})).dequeue("progress").promise("progress") 
 
.then(function() {console.log("complete")});
#progress div { 
 
    background: blue; 
 
    width: 0px; 
 
    height: 20px; 
 
    border: 2px solid green; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<div id="progress"> 
 
    <div></div> 
 
</div> 
 
<div id="result"></div>

Смежные вопросы