2013-11-21 1 views
13

Если я хочу, чтобы синхронные и асинхронные функции выполнялись в определенном порядке, я мог бы использовать jQuery-обещание, но он не работает так, как я ожидал Работа.jQuery Отложенные и обещающие для последовательного выполнения синхронных и асинхронных функций

Функции a, b и c должны выполняться в том порядке, в котором вызывается функция deferred.resolve(). Я ожидаю, что функция b будет выполнена, но все функции выполняются немедленно независимо от того, вызывается ли это решение.

Вот код:

function a(){ 
    var deferred = $.Deferred(); 
    setTimeout(function(){ 
    console.log("status in a:",deferred.state()); 
    //this should trigger calling a or not? 
    deferred.resolve("from a"); 
    },200); 
    console.log("a"); 
    return deferred.promise(); 
}; 
function b(){ 
    var deferred = $.Deferred(); 
    setTimeout(function(){ 
    console.log("status in b:",deferred.state()); 
    deferred.resolve("from b"); 
    },200); 
    console.log("b"); 
    return deferred.promise(); 
} 
//synchronous function 
function c(){ 
    var deferred = $.Deferred(); 
    console.log("c"); 
    console.log("status in c:",deferred.state()); 
    deferred.resolve("from c"); 
    return deferred.promise(); 
} 
function test(){ 
    fn=[a,b,c],i=-1, 
    len = fn.length,d, 
    d = jQuery.Deferred(), 
    p=d.promise(); 
    while(++i<len){ 
    p=p.then(fn[i]); 
    } 
    p.then(function(){ 
    console.log("done"); 
    }, 
    function(){ 
    console.log("Failed"); 
    }); 
    d.resolve(); 
    //instead of the loop doing the following has the same output 
    //p.then(a).then(b).then(c); 
    //d.resolve(); 
} 
test(); 

Выход:

a 
b 
status in c: pending 
c 
done 
status in a: pending 
status in b: pending 

Ожидаемые результаты:

a 
status in a: pending 
b 
status in b: pending 
c 
status in c: pending 
done 

попробовал некоторые комбинации из следующих модификаций:

d = jQuery.Deferred(); 
    setTimeout(function(){d.resolve();},100); 
    var p=d.promise(); 
    while(++i<len){ 
    p.then(fn[i]); 
    } 

Но все с такими же неожиданными результатами, b вызывается до того, как отложен запрос, разрешен, c вызывается до того, как отложенный b будет разрешен.

ответ

9

Для JQuery до 1.8, это проблема, но для новых версий JQuery, это не проблема:

function test(){ 
    var d = jQuery.Deferred(), 
    p=d.promise(); 
    //You can chain jQuery promises using .then 
    p.then(a).then(b).then(c); 
    d.resolve(); 
} 
test(); 

DEMO

Ниже демка JQuery 1.7.2

DEMO

+1

В качестве примечания стороны, чтобы заставить его работать в jQuery 1.7.2 (с использованием собственного кода jq) http://jsfiddle.net/L5nud/2/ –

+1

jQuery <1.8 - это отличная цепочка WRT, вы просто используете .pipe вместо. then. 1.8 просто изменился. Затем будет .pipe. – Esailija

+0

как использовать его, если функция 'a' возвращает значение, использующее функцию' b' и т. Д. –

2

< JQuery 1.8 прекрасно WRT цепочки, вы просто использовать .pipe вместо .then. 1.8 просто изменилось .then будет .pipe.

1

Sidenote: Когда вы используете его без массива, вам не нужно начинать с обещания. $.when({}).then(a).then(b) будет делать трюк просто отлично. Вам нужно только убедиться, что вы не ставите a внутри when.

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

  • Нет связанных вопросов^_^