我有3个函数可以对后端系统进行aync调用:fnOne,fnTwo,fnThree。我知道我做的不正确,但是找不到正确的方法。

我首先尝试在每次完成后称呼他们:

但是,fnOne中已经有一个延迟的对象,解决该问题时,它正在兑现我的承诺。

$.when(oController._fnOne()).done(function(){
    console.log("fn one complete");
});


功能

_fnOne: function(){

    var oController = this;

 //when the deferred is done in _checkInstanceStatus, it is resolving the above, rather than the pDeferred in this function resolving the above.
$.when(oController._checkInstanceStatus(oParams)).done(function(oStatusData) {
        //does some stuff
        return $.Deferred(function() {
            var pDeferred = this;
            //does a call for data and upon success i will resolve ..
            pDeferred.resolve();
        });
    });
}


其他功能

_checkInstanceStatus: function(oParams){
            return $.Deferred(function() {
                var pDeffered = this;
                //does a call for data and upon success i will resolve...
                pDeffered.resolve(data);

                });
            });
        },


然后计划是尝试将它们链接起来,以便它们一个接一个地运行,如下所示:

$.when(oController._fnOne())
.then(oController._fnTwo())
.then(oController._fnThree())
.done(function(){
    console.log("all complete!");
});

最佳答案

有两件事:


如果要传递,则无需使用$.when
fnOne(可能还有其他)需要返回一个promise / Deferred,以便您知道它何时完成。由于它使用的是_checkInstanceStatus并返回Deferred,因此可以使用then来实现:


所以fnOne可能看起来像这样:

fnOne: function() {
    var oController = this;
    return oController.__checkInstanceStatus(oParams).then(function(oStatusData) {
        var pDeferred = $.Deferred();
        callAmazon(function() {
            if (/*successful*/) {
                pDeferred.resolve();
            } else {
                pDeferred.reject();
            }
        });
        return pDeferred.promise(); // Or just the Deferred if you like, but
                                    // normally you want to share promises, not
                                    // Deferred objects
    });
}


注意,它如何返回调用then的结果,这是通过调用then创建的承诺。该承诺将根据您从then处理程序返回的承诺来解决。

您将对其他功能遵循相同的模式。

要将它们一个接一个地链接,您可以这样做:

oController._fnOne()
.then(oController._fnTwo)        // Notice no () on that, we're passing the
.then(oController._fnThree)      // function in, not calling it. Same on this line.
.then(function() {
    console.log("all complete!");
})
.catch(function(error) {
    // Do something about the error
});


(我假设_fnOnefnOne是相同的函数。)

我假设相对较新的jQuery在Deferreds中具有Promises支持。



旁注:我将改用本机Promises(必要时使用polyfill以支持旧的浏览器),而不是使用jQuery的Deferred,它具有丰富的历史,并且API变得笨拙。 :-)

带有原生承诺:

fnOne: function() {
    var oController = this;
    return oController.__checkInstanceStatus(oParams).then(function(oStatusData) {
        return new Promise(function(resolve, reject) {
            callAmazon(function() {
                if (/*successful*/) {
                    resolve();
                } else {
                    reject();
                }
            });
        });
    });
}


用法是相同的(因为我使用了第一个示例中已添加到Deferred的Promise API)。

关于javascript - 延期 promise -每次完成后一次运行功能,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/43784439/

10-10 04:19