国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

拒絕不會在鏈?zhǔn)匠兄Z中傳播
P粉193307465
P粉193307465 2023-10-23 17:50:47
0
2
3051

我無法理解為什么拒絕不通過承諾鏈傳遞,我希望有人能夠幫助我理解原因。對我來說,將功能附加到一系列承諾意味著我依賴于要履行的原始承諾的意圖。這很難解釋,所以讓我先展示我的問題的代碼示例。 (注意:本示例使用 Node 和延遲節(jié)點模塊。我使用 Dojo 1.8.3 對此進(jìn)行了測試,并得到了相同的結(jié)果)

var d = require("deferred");

var d1 = d();

var promise1 = d1.promise.then(
    function(wins) { console.log('promise1 resolved'); return wins;},
    function(err) { console.log('promise1 rejected'); return err;});
var promise2 = promise1.then(
    function(wins) { console.log('promise2 resolved'); return wins;},
    function(err) { console.log('promise2 rejected'); return err;});
var promise3 = promise2.then(
    function(wins) { console.log('promise3 resolved'); return wins;},
    function(err) { console.log('promise3 rejected'); return err;});
d1.reject(new Error());

運行此操作的結(jié)果是這樣的輸出:

promise1 rejected
promise2 resolved
promise3 resolved

好吧,對我來說,這個結(jié)果沒有意義。通過附加到這個 Promise 鏈,每個 then 都暗示著這樣的意圖:它將依賴于 d1 的成功解析以及沿著鏈傳遞的結(jié)果。如果promise1中的promise沒有收到wins值,而是在其錯誤處理程序中收到一個err值,那么鏈中的下一個promise怎么可能調(diào)用它的success函數(shù)呢?它無法將有意義的值傳遞給下一個 Promise,因為它本身沒有獲得值。

我可以用另一種方式來描述我的想法:有三個人:John、Ginger 和 Bob。約翰擁有一家小部件商店。金杰走進(jìn)他的店里,要了一袋各種顏色的小部件。他沒有庫存,因此他向經(jīng)銷商發(fā)送請求,要求將它們運送給他。與此同時,他給了金杰一張雨支票,說他欠她那袋小部件。鮑勃發(fā)現(xiàn)金杰正在獲取這些小部件,并要求他在她用完這些小部件后獲取藍(lán)色的小部件。她同意了,并給了他一張紙條,表示她會同意。現(xiàn)在,約翰的經(jīng)銷商在他們的供應(yīng)中找不到任何小部件,并且制造商不再生產(chǎn)這些小部件,因此他們通知約翰,約翰又通知金杰她無法獲得這些小部件。當(dāng) Bob 自己沒有得到任何東西時,他如何能夠從 Ginger 那里得到藍(lán)色小部件?

我對這個問題的第三個更現(xiàn)實的觀點是這樣的。假設(shè)我有兩個值想要更新到數(shù)據(jù)庫。一個依賴于另一個的 id,但在我將其插入數(shù)據(jù)庫并獲得結(jié)果之前,我無法獲取 id。最重要的是,第一次插入取決于數(shù)據(jù)庫的查詢。數(shù)據(jù)庫調(diào)用返回的承諾是我用來將兩個調(diào)用鏈接成一個序列的。

var promise = db.query({parent_id: value});
promise.then(function(query_result) {
    var first_value = {
        parent_id: query_result[0].parent_id
    }
    var promise = db.put(first_value);
    promise.then(function(first_value_result) {
        var second_value = {
            reference_to_first_value_id: first_value_result.id
        }
        var promise = db.put(second_value);
        promise.then(function(second_value_result) {
            values_successfully_entered();
        }, function(err) { return err });
    }, function(err) { return err });
}, function(err) { return err });

現(xiàn)在,在這種情況下,如果 db.query 失敗,它將調(diào)用第一個 then 的 err 函數(shù)。但隨后它會調(diào)用下一個承諾的成功函數(shù)。雖然該 Promise 期望第一個值的結(jié)果,但它會從其錯誤處理函數(shù)獲取錯誤消息。

所以,我的問題是,如果我必須測試成功函數(shù)中的錯誤,為什么還要有錯誤處理函數(shù)?

抱歉,這篇文章太長了。我只是不知道如何用另一種方式解釋它。

更新和更正

(注意:我刪除了我曾經(jīng)對某些評論做出的回復(fù)。因此,如果有人對我的回復(fù)發(fā)表評論,那么既然我刪除了它,他們的評論可能會顯得斷章取義。對此表示抱歉,我試圖將其保留為盡可能短。)

謝謝大家的回復(fù)。我首先想向大家道歉,因為我的問題寫得這么差,尤其是我的偽代碼。我有點過于激進(jìn)地試圖保持簡短。

感謝 Bergi 的回復(fù),我想我發(fā)現(xiàn)了我的邏輯錯誤。我想我可能忽略了導(dǎo)致我遇到問題的另一個問題。這可能導(dǎo)致承諾鏈的工作方式與我想象的不同。我仍在測試代碼的不同元素,所以我什至無法形成一個正確的問題來看看我做錯了什么。不過,我確實想向大家通報最新情況,并感謝你們的幫助。

P粉193307465
P粉193307465

全部回復(fù)(2)
P粉155710425

@Jordan 首先,正如評論者指出的,當(dāng)使用延遲庫時,您的第一個示例肯定會產(chǎn)生您期望的結(jié)果:

promise1 rejected
promise2 rejected
promise3 rejected

其次,即使它會產(chǎn)生您建議的輸出,它也不會影響第二個代碼段的執(zhí)行流程,這有點不同,更像是:

promise.then(function(first_value) {
    console.log('promise1 resolved');
    var promise = db.put(first_value);
    promise.then(function (second_value) {
         console.log('promise2 resolved');
         var promise = db.put(second_value);
         promise.then(
             function (wins) { console.log('promise3 resolved'); },
             function (err) { console.log('promise3 rejected'); return err; });
    }, function (err) { console.log('promise2 rejected'); return err;});
}, function (err) { console.log('promise1 rejected'); return err});

并且,如果第一個承諾被拒絕,只會輸出:

promise1 rejected

然而(到達(dá)最有趣的部分)即使延遲庫肯定返回 3 x returned,大多數(shù)其他承諾庫將返回 1 x returned, 2 x 已解決(這導(dǎo)致假設(shè)您通過使用其他一些 Promise 庫獲得了這些結(jié)果)。

另外令人困惑的是,其他庫的行為更加正確。讓我解釋一下。

在同步世界中,“承諾拒絕”的對應(yīng)部分是拋出。因此從語義上講,同步中的異步 deferred.reject(new Error()) 等于 throw new Error()。 在您的示例中,您不會在同步回調(diào)中??拋出錯誤,您只是返回它們,因此您切換到成功流程,其中錯誤是成功值。為了確保拒絕進(jìn)一步通過,您需要重新拋出錯誤:

function (err) { console.log('promise1 rejected'); throw err; });

現(xiàn)在的問題是,為什么延遲庫將返回的錯誤視為拒絕?

原因是延遲工作中的拒絕有點不同。在 deferred lib 中,規(guī)則是:當(dāng)出現(xiàn)錯誤實例時,promise 會被拒絕,因此即使你執(zhí)行 deferred.resolve(new Error()) 它也會起作用如 deferred.reject(new Error()) ,如果你嘗試執(zhí)行 deferred.reject(notAnError) ,它會拋出一個異常,表示該 Promise 只能被拒絕有錯誤的實例。這清楚地表明了為什么從 then 回調(diào)返回的錯誤拒絕了承諾。

延遲邏輯背后有一些有效的推理,但它仍然與 JavaScript 中 throw 的工作方式不符,因此,此行為計劃在延遲的 v0.7 版本中進(jìn)行更改。

簡短摘要:

為了避免混亂和意外結(jié)果,只需遵循良好實踐規(guī)則:

  1. 始終拒絕帶有錯誤實例的承諾(遵循同步世界的規(guī)則,其中拋出非錯誤的值被視為不好的做法)。
  2. 通過拋出錯誤拒絕同步回調(diào)(返回錯誤并不能保證拒絕)。

遵守上述規(guī)定,您將在延遲庫和其他流行的 Promise 庫中獲得一致且預(yù)期的結(jié)果。

P粉376738875

沒有。您所描述的不是一個鏈,而只是將所有回調(diào)附加到d1。然而,如果您想使用 then 鏈接某些內(nèi)容,promise2 的結(jié)果取決于 promise1 的分辨率以及 promise1 的分辨率以及 然后回調(diào)處理了它。

文檔指出:

.then 方法通常根據(jù) Promises 來看待/A 規(guī)范(或者更嚴(yán)格的Promsises/A+ )。這意味著回調(diào) shell 返回的 Promise 將被同化為 Promise2 的解析,如果沒有成功/錯誤處理程序,相應(yīng)的結(jié)果將直接傳遞給 Promise2 code> - 因此您可以簡單地省略處理程序來傳播錯誤。

但是,如果錯誤被處理,則生成的 promise2 被視為已修復(fù),并將用該值來實現(xiàn)。如果您不希望出現(xiàn)這種情況,則必須重新拋出錯誤,就像在 try-catch 子句中一樣?;蛘撸梢詮奶幚沓绦蚍祷匾粋€(待)拒絕的承諾。不確定 Dojo 的拒絕方式是什么,但是:

var d1 = d();

var promise1 = d1.promise.then(
    function(wins) { console.log('promise1 resolved'); return wins;},
    function(err) { console.log('promise1 rejected'); throw err;});
var promise2 = promise1.then(
    function(wins) { console.log('promise2 resolved'); return wins;},
    function(err) { console.log('promise2 rejected'); throw err;});
var promise3 = promise2.then(
    function(wins) { console.log('promise3 resolved'); return wins;},
    function(err) { console.log('promise3 rejected'); throw err;});
d1.reject(new Error());

他不應(yīng)該能夠。如果沒有錯誤處理程序,他只會感知到?jīng)]有剩余小部件的消息(((來自約翰)來自 Ginger)。然而,如果金格為這種情況設(shè)置了一個錯誤處理程序,如果約翰或他的經(jīng)銷商沒有剩下藍(lán)色的小部件,她仍然可以履行她的承諾,從她自己的小屋里給鮑勃一個小部件,給他一個綠色的小部件。

要將錯誤回調(diào)轉(zhuǎn)換為元,從處理程序返回錯誤就像說“如果沒有留下任何小部件,只需給他一個注釋,即沒有留下任何小部件 - 這是與所需的小部件一樣好”。

...這意味著錯誤已在那里處理。如果您不這樣做,只需省略錯誤回調(diào)即可。順便說一句,您的成功回調(diào)不會返回它們正在創(chuàng)建的承諾,因此它們似乎毫無用處。正確的是:

var promise = db.query({parent_id: value});
promise.then(function(query_result) {
    var first_value = {
        parent_id: query_result[0].parent_id
    }
    var promise = db.put(first_value);
    return promise.then(function(first_value_result) {
        var second_value = {
            reference_to_first_value_id: first_value_result.id
        }
        var promise = db.put(second_value);
        return promise.then(function(second_value_result) {
            return values_successfully_entered();
        });
    });
});

或者,由于您不需要閉包來訪問先前回調(diào)的結(jié)果值,甚至:

db.query({parent_id: value}).then(function(query_result) {
    return db.put({
        parent_id: query_result[0].parent_id
    });
}).then(function(first_value_result) {
    return db.put({
        reference_to_first_value_id: first_value_result.id
    });
}.then(values_successfully_entered);
最新下載
更多>
網(wǎng)站特效
網(wǎng)站源碼
網(wǎng)站素材
前端模板