2014-07-03 51 views
0

我想顯示一些單詞,然後當它完成時顯示完整的句子。

這個問題並不重要,我嘗試,它一起玩。不是一個接一個。

你們其中一個人可以向我解釋我做錯了什麼嗎?

function DisplayHdline(callback){ 
    var str = "HELP STOP CRUELTY NOW."; 
    var spans = '<span>' + str.split(/\s+/).join(' </span><span>') + '</span>'; 

    jQuery(spans).hide().appendTo('#vidheadline').each(function(i) { 
     jQuery(this).delay(2000 * i).fadeIn('fast').delay(1000).fadeOut(50); 
    }); 
    callback(); 
} 

function addComplete(){ 
    jQuery('LOREM IPSUM DOLLOR').appendTo('#vidheadline').fadeIn(); 
    //alert('Where is my sentence'); 
} 

DisplayHdline(function(){ 
    jQuery.when(this).done(addComplete()); 
}); 

//jQuery.when(DisplayHdline()).then(addComplete()); 

感謝

詩:我做了搜索,並試圖在這裏找到不同sollutions。但都具有相同的結果,所以顯然,我做錯了什麼

編輯:這是我結束了 功能typePlay(){VAR = actionStr「幫助停止NOW殘酷對待。」 var spans =''+ actionStr.split(/ \ s + /)。join('')+'';

function DisplayHdline(){ 
     return jQuery(spans).hide().appendTo('#vidheadline').each(function(i) { 
      jQuery(this).delay(2000 * i).fadeIn('fast').delay(1000).fadeOut(50); 
     }).promise(); 
    } 

    function addComplete(){ 
     jQuery('#vidheadline').hide().append('<p id="completeHeadline">' +actionStr+'</p>').fadeIn(); 
    } 

    DisplayHdline().done(addComplete); 

}

window.setInterval(function typeTimer(){ 
     jQuery('#vidheadline').empty(); 
     typePlay(); 
    }, 25000); 

typePlay().done(typeTimer); 

感謝 ;)

回答

1

回調和延遲是鏈接異步操作的兩種不同技術。你做一個,或者其他。

$.when不在意DisplayHdLine()接受回調;它期望的是它返回一個Deferred(或Promise),它不會。

使用回調的方法,你想要是;

DisplayHdline(addComplete); 

但是,你再有你在錯誤的地方調用內DisplayHdLinecallback問題。一旦你的所有元素都消失了,你就需要調用它。最簡單的方法是使用promise();

function DisplayHdline(callback){ 
    var str = "HELP STOP CRUELTY NOW."; 
    var spans = '<span>' + str.split(/\s+/).join(' </span><span>') + '</span>'; 

    jQuery(spans).hide().appendTo('#vidheadline').each(function(i) { 
     jQuery(this).delay(2000 * i).fadeIn('fast').delay(1000).fadeOut(50); 
    }).promise().done(callback); 
} 

你那麼對於這個完整的代碼如下:

function DisplayHdline(callback){ 
    var str = "HELP STOP CRUELTY NOW."; 
    var spans = '<span>' + str.split(/\s+/).join(' </span><span>') + '</span>'; 

    jQuery(spans).hide().appendTo('#vidheadline').each(function(i) { 
     jQuery(this).delay(2000 * i).fadeIn('fast').delay(1000).fadeOut(50); 
    }).promise().done(callback); 
} 

function addComplete(){ 
    jQuery('LOREM IPSUM DOLLOR').appendTo('#vidheadline').fadeIn(); 
    //alert('Where is my sentence'); 
} 

DisplayHdline(addComplete); 

然而,正如你現在使用中DisplayHdline deferreds ,你可以從DisplayHdline回報的承諾,這可能會給你更清潔的代碼:

function DisplayHdline(){ 
    var str = "HELP STOP CRUELTY NOW."; 
    var spans = '<span>' + str.split(/\s+/).join(' </span><span>') + '</span>'; 

    return jQuery(spans).hide().appendTo('#vidheadline').each(function(i) { 
     jQuery(this).delay(2000 * i).fadeIn('fast').delay(1000).fadeOut(50); 
    }).promise(); 
} 

function addComplete(){ 
    jQuery('LOREM IPSUM DOLLOR').appendTo('#vidheadline').fadeIn(); 
    //alert('Where is my sentence'); 
} 

DisplayHdline().done(addComplete); 

另外,請注意之間的區別函數(正如我一直在做的,沒有())vs調用函數(你一直在做)。欲瞭解更多信息,請參閱Why is the method executed immediately when I use setTimeout?

+0

感謝您的解釋馬特,真的幫助。當我查看jQuery文檔時,我看到的幾個例子沒有.promise();我必須承認我對此很新穎。偉大到現在,當時和完成將需要諾言(); – user3750757

4

似乎有一個非常普遍的誤解,認爲承諾的功能,如jQuery.when()含有一些神奇的力量,他們可以只是「知道」時,其他一些功能已完成。現在讓我解開這個神話。他們沒有任何魔力。 jQuery.when()只承諾承諾,因爲它的論點和它需要承諾的原因是因爲這些承諾將告訴jQuery.when()何時完成。當你將其他類型的對象傳遞給jQuery.when()這不是承諾時,它完全不知道何時完成了其他事情。它會將它視爲一個同步函數,只要它運行就完成,但如果它不是一個同步函數或根本不是函數,那麼jQuery.when()將不會執行您想要的操作。


規則#1 - 您必須將承諾傳遞給jQuery.when()。你沒有這樣做。您將this傳遞給它,可能是window對象。這不會對你有任何好處,jQuery.when()將立即解決,而不是等待任何事情完成。

規則#2 - 只有在編寫解決或拒絕異步任務完成時的承諾的代碼的承諾纔有效。再一次,這裏沒有魔法。當異步任務完成時,你必須告訴承諾。只有這樣,這個承諾能夠做到它應該做的事情,並且使得處理程序能夠工作,如.then()。您的DisplayHdline()函數中有幾個異步操作,但您並未創建承諾或解決該承諾,而且您也沒有跟蹤該函數中的所有異步操作何時完成。

規則#3 - 如果你的基本框架/基礎設施支持的承諾,將解決他們爲你當操作完成,然後通過各種手段使用,而不是創建自己的承諾。在你的情況下,jQuery動畫已經創建並解決了他們自己的承諾。你會想在這裏使用它。


所以,如果在這裏你的問題的程度,你想知道什麼時候在DisplayHdline()所有的動畫完成後,你可以利用jQuery來幫助您瞭解這一點,你可以從這樣的函數返回一個承諾這樣的:

function DisplayHdline() { 
    var str = "HELP STOP CRUELTY NOW."; 
    var spans = '<span>' + str.split(/\s+/).join(' </span><span>') + '</span>'; 

    return jQuery(spans).hide().appendTo('#vidheadline').each(function(i) { 
     jQuery(this).delay(2000 * i).fadeIn('fast').delay(1000).fadeOut(50); 
    }).promise(); 
} 

然後,你可以調用它,知道什麼時候它的完成這樣的:

DisplayHdline().done(function() { 
    // code here to execute when everything in DisplayHdline is done 
}); 

請注意,我改變了你的代碼的結構不通過交流因爲這個結構更加靈活,所以可以優化到DisplayHdline()。當您返回承諾時,您可以隨時像我所做的那樣添加.done()處理程序,它將像回調一樣工作,但您也可以執行許多其他操作,例如將其他操作鏈接到此處或將其與其他操作組合在一起並等待在做其他事情之前要做好多重承諾......等等,這是標準承諾接口的美妙之處,因爲它允許許多不同類型的處理,而不必知道操作的內部。


jQuery在這裏爲您做的是實際上爲您節省了大量工作。當你在一個集合上做了.promise()的動畫時,jQuery向你返回一個單一的承諾,當所有的底層對象的承諾都被解決時,jQuery會解決這個承諾,節省你跟蹤所有承諾的工作。這實際上非常有用。

0

這是因爲你的函數沒有返回一個承諾。你只是使用回調機制,承諾用於異步調用,以避免回調地獄。

你可以改變你的代碼是這樣的:

DisplayHdLine(function() { 
    // When you're inside this function, everything in the DisplayHdLine is done executing 
    addComplete(); 
}); 

甚至更​​短的

DisplayHdLine(addComplete); 

如果你想被稱爲回調函數,當衰落完成後,您可以打開你的jquery.each進入承諾並在done函數中調用回調函數。

function DisplayHdline(callback){ 
    var str = "HELP STOP CRUELTY NOW."; 
    var spans = '<span>' + str.split(/\s+/).join(' </span><span>') + '</span>'; 

    jQuery(spans).hide().appendTo('#vidheadline').each(function(i) { 
     jQuery(this).delay(2000 * i).fadeIn('fast').delay(1000).fadeOut(50); 
    }).promise().done(callback); 
} 
相關問題