本文介绍了延期承诺-每次完成后一一运行功能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have 3 functions that make aync calls to backend systems : fnOne, fnTwo, fnThree. I know I am not doing it correctly, but cannot figure out the right way.

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

I am starting off by trying to call them one by after each completes:

但是,fnOne内部已经有一个延迟的对象,当该对象解决时,它正在兑现我的诺言.

However, fnOne already has a deferred object inside of it and when that is resolved it is resolving my promise.

$.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);

                });
            });
        },

然后计划是尝试将它们链接起来,以便它们一个接一个地运行,就像这样:

Then the plan is to try and chain them, so they run one by one, like so:

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

推荐答案

以下几点:

  1. 如果将单个Deferred传递给$.when,则无需使用.

fnOne(可能还有其他)需要返回一个承诺/延迟,以便您知道它何时完成.由于它使用的是_checkInstanceStatus并返回Deferred,因此可以使用then:

fnOne (and presumably the others) needs to return a promise/Deferred so you know when it completes. Since it's using _checkInstanceStatus, which returns a Deferred, it can do that by using then:

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

So fnOne might look like this:

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处理程序返回的承诺来解决.

Notice how it returns the result of calling then, which is a promise created by calling then. That promise will resolve based on the promise you're returning from the then handler.

其他功能将遵循相同的模式.

You'd follow the same pattern with the other functions.

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

To chain them one after another, you'd do this:

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是相同的函数.)

(I'm assuming _fnOne and fnOne are the same function.)

我假设jQuery的最新版本在Deferreds中具有Promises支持.

I'm assuming a relatively recent version of jQuery that has Promises support in Deferreds.

侧面说明:我将改用本机Promises(必要时使用polyfill以支持旧的浏览器),而不是使用jQuery的Deferred,它具有...很好的历史,并且API具有变得笨拙. :-)

Side note: I'd switch to using native Promises (with a polyfill if necessary to support old browsers) rather than using jQuery's Deferred, which has...well, it has a lot of history and the API has gotten cumbersome. :-)

具有原生承诺:

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).

Usage is the same (because I used Promise APIs that have been added to Deferred in the first example).

这篇关于延期承诺-每次完成后一一运行功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-15 08:20