簡體   English   中英

延遲/承諾相互依賴

[英]Deferred/Promise dependency on each other

我想實現Deferred / Promise的依賴調用。 問題是我不明白如何逐步調用包含異步調用的處理程序數組,例如

我有全局對象:

var options = {
    additionalHandler: []
    main : null
}

然后添加主函數和處理程序,它們添加強順序,並且還需要調用此序列

options.main = function(that, data){
    var that = this; //Todo: fix this should be button
    //Do some staff
}

var dialog = $(somedialog).dialog({
    autoOpen: false,
    modal: true,
    buttons: {
        "OK": function() {                            
            //There is the place where i have wait user answer to invoke innerDeferred.resolve(true) that is have to affected on global Deferred
            $(this).dialog("close");
        }
    },
    close: function () {
        //innerDeferred.resolve(false);
    }
});

options.additionalHandler.push(function(){
    dialog.dialog("open");
})

比按鈕單擊時,我運行/等待所有處理程序,然后執行main函數,如果所有處理程序都返回true

$("#someButton").on("click", function () {
    var self = this;
    if(typeof options !== "undefined"){
        var deferred = $.Deferred();
        if (options.additionalHandler &&  options.additionalHandler.length) // if we do not have(collect) any handlers we don't ran it all
        {
            $(options.additionalHandler).each(function () {
                if (typeof this !== "undefined" && typeof this === "function") {
                    deferred.then(this( /*??? deferred or innerDeferred */));
                }
            });
        }
        deferred.done(function (def) {
            if(def) // if all steps from all inner steps return true 
                options.main(self , someData));
        });               
    }
}

這意味着我有一個主處理程序依賴於可能不存在的其他處理程序答案(如果不存在我們只是去主處理程序),問題是如何實現對async內部延遲調用結果的依賴,它應該逐步運行步驟(我們的情況下對話框等待用戶回答並轉到另一個對話框或可能的ajax調用)。

UPDATE1:

從上到下這是偽實現(代碼),也不起作用

這是如何工作的(必填):

user => add some itemp to backet
backet <= knows about some discount if user purchase 2 items and register new pop-up that says if you add 2 you'll have 50% sale.
user => add another item to backet 
backet <= this item will not available till next week, register another pop-up.
user = > push Order
Order => (pop-up) Discount if 2 do you (Yes-break /No -continue) => Item available on next week will wait ( Yes - continue/ No- break) => if (all.Continue) => push Order.

所有都作為瀑布,我沒有看到延遲/承諾的利弊

代碼中有幾個問題。

您的deferred變量仍然是指原始的Deferred ,它是空的,您需要在每次添加回調時更新deferred

deferred = deferred.then(this( /*??? deferred or innerDeferred */));

你檢查true內部完成方法,你需要確保所有的回調都返回true (至少是最后一個)。

如果您使用async回調,請確保它們返回返回true的deffered實例。

最后,你傳遞給options.main的第一個參數無關緊要,因為你在方法中覆蓋了它。

以下是promises上序列異步操作實現的解決方案:

這里開始

 <!DOCTYPE html> <html> <head> <script src="https://code.jquery.com/jquery-1.12.4.js" integrity="sha256-Qw82+bXyGq6MydymqBxNPYTaUXXq7c8v3CwiYwLLNXU=" crossorigin="anonymous"></script> <script src="https://code.jquery.com/ui/1.12.0/jquery-ui.js" integrity="sha256-0YPKAwZP7Mp3ALMRVB2i8GXeEndvCq3eSl/WsAl1Ryk=" crossorigin="anonymous"></script> <link rel="stylesheet" href="https://code.jquery.com/ui/1.12.0/themes/smoothness/jquery-ui.css" crossorigin="anonymous"> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous"> <!-- Latest compiled and minified JavaScript --> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script> <script> $(function() { var options = { additionalHandler: [], main : null } options.main = function(confirmed){ $("#result").html("Confirmed: " + confirmed); }; options.additionalHandler.push(function(resolve, reject, data){ var dialog1 = $("#dialog1").dialog({ autoOpen: false, modal: true, buttons: { "OK": function() { resolve(true); $(this).dialog("close"); } }, close: function () { resolve(false); } }); dialog1.dialog("open"); }); options.additionalHandler.push(function(resolve, reject, data){ var dialog2 = $("#dialog2").dialog({ autoOpen: false, modal: true, buttons: { "OK": function() { resolve(true); $(this).dialog("close"); } }, close: function () { resolve(false); } }); dialog2.dialog("open"); }); Array.prototype.chainExecute = function(data){ var array = this; var results = []; return array.reduce(function(previous, current) { return previous.then(function(result) { return new Promise(function(resolve, reject) { current(resolve, reject, data); }).then(function(result) { results.push(result); return results; }); }); }, Promise.resolve()); }; $("#orderPush").on("click", function () { var self = this; if(typeof options !== "undefined") { options.additionalHandler.chainExecute("Blah").then(function(result) { options.main(result); }, function(reason) { options.main(reason); }) } }); }); </script> </head> <body> <div id="dialog1" style="display: none"> <div>Discount if 2 items!</div> </div> <div id="dialog2" style="display: none"> <div>Been available on next week!</div> </div> <button type="button" class="btn btn-primary" id="orderPush">Process order</button> <p><strong id="result"></strong></p> </body> </html> 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM