javascript - Deferred Promise - 在每个函数完成后一个一个地运行函数

标签 javascript jquery promise deferred

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

我首先尝试在每个完成后调用它们:

但是,fnOne 内部已经有一个延迟对象,当它被解析时,它就是在解析我的 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);

                });
            });
        },

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

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

最佳答案

一些事情:

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

  2. fnOne(可能还有其他)需要返回一个 promise/Deferred 以便您知道它何时完成。由于它使用返回 Deferred 的 _checkInstanceStatus,因此它可以通过使用 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 创建的 promise 。该 promise 将根据您从 then 处理程序返回的 promise 来解决。

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

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

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 变得很麻烦。 :-)

原生 promise :

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 - Deferred Promise - 在每个函数完成后一个一个地运行函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43784439/

相关文章:

javascript - 使用 javascript/jQuery 对选择列表中的选项进行排序...但不是按字母顺序排序

javascript - 按顺序遍历未确定数量的 Promise

javascript - 检测浏览器自动填充

jquery - 使用 jQuery 来确定一个 div 的 child 是否有一个 css 类

jquery - 我无法阻止 Chrome 中的鼠标滚轮事件

javascript - ElasticSearch JavaScript promise

javascript - Async/Await 导致循环

javascript - 具有共享和拆分工具提示的 Highcharts,是否可以设置悬停 xAxis 标签的样式?

javascript - 如何使用 xsl 值作为 onclick 的 ID

javascript - 内部函数使用 setTimeout 调用父函数