亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

jQuery$.延遲固有的問題(jQuery 1.x/2.x)

jQuery$.延遲固有的問題(jQuery 1.x/2.x)

慕容森 2019-07-03 16:46:45
jQuery$.延遲固有的問題(jQuery 1.x/2.x)有一篇關于jQuery延遲對象失敗的非常詳盡的文章:你錯過了承諾的要點..在這篇文章中,多梅尼奇強調了jQuery承諾與其他承諾相比的一些缺點,包括Q、RSVP.js和ES6承諾。我離開了多梅尼奇的文章,覺得jQuery承諾在概念上有一個固有的缺陷。我想舉例說明這個概念。我認為jQuery實現有兩個關注點:1..then方法是不可鏈接的。換句話說promise.then(a).then(b)jQuery將調用a然后b當promise都實現了。自.then在其他承諾庫中返回一個新的承諾,它們的等效值是:promise.then(a)promise.then(b)2.jQuery中出現異常處理。另一個問題似乎是異常處理,即:try {   promise.then(a)} catch (e) {}在Q中相當于:try {   promise.then(a).done()} catch (e) {    // .done() re-throws any exceptions from a}在jQuery中,當a捕獲塊失敗。在另一個承諾中,任何例外a會被帶到.done或.catch或者其他異步捕獲。如果所有的承諾API調用都沒有捕獲異常,那么它就消失了(因此,使用.done若要釋放任何未處理的異常,請執行以下操作。 上面的問題是否涵蓋了jQuery承諾實現的問題,還是我誤解或忽略了一些問題?編輯此問題涉及jQuery<3.0;jQuery3.0alphajQuery是答應/A+兼容的。
查看完整描述

3 回答

?
慕仙森

TA貢獻1827條經驗 獲得超8個贊

jQuery3.0修復了下面概述的問題。這是真正的承諾/A+符合。

是的,jQuery承諾存在嚴重的固有問題。

盡管如此,由于這篇文章是寫的,jQuery做出了很大的努力,希望成為更多的承諾/Aplus抱怨,現在他們有了一種.然后鏈接的方法。

所以即使在jQuery中returnsPromise().then(a).then(b)用于承諾返回函數ab將按預期工作,在繼續前進之前展開返回值。如圖所示小提琴:

function timeout(){
    var d = $.Deferred();
    setTimeout(function(){ d.resolve(); },1000);
    return d.promise();}timeout().then(function(){
   document.body.innerHTML = "First";
   return timeout();}).then(function(){
   document.body.innerHTML += "<br />Second";
   return timeout();}).then(function(){
   document.body.innerHTML += "<br />Third";
   return timeout();});

然而,這兩個巨量jQuery的問題是錯誤處理和意外執行順序。

錯誤處理

與CATCH不同,即使您解決了jQuery承諾,也無法將其標記為“已處理”。這使得jQuery中的拒絕固有地中斷,并且非常難以使用,這與同步沒有什么相似之處。try/catch.

你能猜到這里有什么日志嗎?小提琴)

timeout().then(function(){
   throw new Error("Boo");}).then(function(){
   console.log("Hello World");},function(){
    console.log("In Error Handler");   }).then(function(){
   console.log("This should have run");}).fail(function(){
   console.log("But this does instead"); });

如果你猜到"uncaught Error: boo"你是對的。jQuery的承諾是不扔保險柜..它們將不允許您處理任何拋出的錯誤,而不是承諾/Aplus承諾。拒絕安全怎么辦?小提琴)

timeout().then(function(){
   var d = $.Deferred(); d.reject();
   return d;}).then(function(){
   console.log("Hello World");},function(){
    console.log("In Error Handler");   }).then(function(){
   console.log("This should have run");}).fail(function(){
   console.log("But this does instead"); });

以下日志"In Error Handler" "But this does instead"-根本無法處理jQuery承諾的拒絕。這與您所期望的流程不同:

try{
   throw new Error("Hello World");} catch(e){
   console.log("In Error handler");}console.log("This should have run");

這就是承諾/A+庫(如Bluebird和Q)的流程,以及您期望的有用性。這是巨量拋出安全是承諾的一個重要賣點。這是藍鳥在這種情況下動作正確.

執行命令

jQuery將執行傳遞的函數。立馬如果底層承諾已經解決,而不是推遲它,那么代碼的行為將有所不同,這取決于我們向拒絕的處理程序附加的承諾是否已經解決。這是有效的釋放扎爾戈會引起一些最痛苦的蟲子。這就產生了一些最難調試的bug。

如果我們查看以下代碼:小提琴)

function timeout(){
    var d = $.Deferred();
    setTimeout(function(){ d.resolve(); },1000);
    return d.promise();}console.log("This");var p = timeout();p.then(function(){
   console.log("expected from an async api.");});console.log("is");setTimeout(function(){
    console.log("He");
    p.then(function(){
        console.log("?????Z???????A?????L????????G???????O???!????? *");
    });
    console.log("Comes");},2000);

我們可以觀察到,哦,如此危險的行為,setTimeout等待原始超時結束,因此jQuery切換其執行順序,因為.。誰喜歡不會導致堆棧溢出的確定性API?這就是為什么允諾/A+規范要求承諾總是被推遲到事件循環的下一次執行。

旁注

值得一提的是,更新更強的承諾庫,如藍鳥庫(以及實驗時)不需要.done在鏈的末尾,就像Q一樣,因為它們自己發現了未處理的拒絕,它們也比jQuery承諾或Q承諾要快得多。


查看完整回答
反對 回復 2019-07-03
?
翻翻過去那場雪

TA貢獻2065條經驗 獲得超14個贊

這幾乎不是一個黑暗的巫毒把戲,沒有必要去尋找它的來源。自從jQuery 1.8發布以來,文檔已經讀過了"these filter functions can return a new value to be passed along to the promise's .done() or .fail() callbacks, or they can return another observable object (Deferred, Promise, etc) which will pass its resolved / rejected status and values to the promise's callbacks"..因此,并不是一個“大問題”,如果你活著,實際上根本不是一個問題

查看完整回答
反對 回復 2019-07-03
  • 3 回答
  • 0 關注
  • 428 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號