JS/jQuery 承诺

Posted

技术标签:

【中文标题】JS/jQuery 承诺【英文标题】:JS/jQuery Promise 【发布时间】:2019-07-08 10:16:10 【问题描述】:

我尝试使用 jQuery 处理 JS 承诺。 我有一连串这样的承诺:

function myPromisesChain(data)

    return $.when(data)
        .then(firstStep)
        .then(secondptStep)
        .then(thirdStep)
        // ...n Step
        .then(finalStep)
        .always(function(data)
            console.log('FINISHED: ' + JSON.stringify(data));
        );

这很好,但是如果我需要在循环中执行一个步骤,该怎么办?伤心,但到目前为止我找不到正确的语法......我期待这样的事情(大约):

    function myPromisesChain(data)

    return $.when(data)
        .then(firstStep)
        .then(secondptStep)            
        .then(function(data)
            var counter = 0;
            var limit = 3;
            while(counter<limit)
                  thirdStep(data.transaction[counter]);
                  counter++;
            
            return data;
        )
        // ...n Step
        .then(finalStep)
        .always(function(data)
            console.log('FINISHED: ' + JSON.stringify(data));
        );

问题是循环中的函数本身就是一个承诺。

【问题讨论】:

看看这个:***.com/a/6558326/529544 你可能想看看async/await 您的问题需要在这里澄清另一点,您要循环执行thirdStep。但是你想串联还是并联执行?如果你想串行执行,我的解决方案可以工作,如果你想并行执行,你需要使用@effective-robot提供的解决方案 【参考方案1】:

每个then 方法都返回一个新的Promise,在另一个then 上调用then 意味着,您正在对前一个then 返回的Promise 调用第二个then

所以你可以保存之前then返回的Promise的引用,并使用它绑定新的then

需要循环内的IIFE来保存执行时对计数器值的引用

function myPromisesChain(data) 
    var promise = $.when(data)
        .then(firstStep)
        .then(secondptStep);

    var counter = 0;
    var limit = 3;
    while (counter < limit) 
        promise = (function (counter) 
            return promise.then(function(data) 
                return thirdStep(data.transaction[counter]);
            );
        )(counter++);
    

    return promise
        // ...n Step
        .then(finalStep)
        .always(function (data) 
            console.log('FINISHED: ' + JSON.stringify(data));
        );

【讨论】:

您每次循环都会覆盖promise。最后,您只需等待最后一个,而不是其他任何一个。 另外,你有 infamous loop issue 和 counter 变量。 别介意我的第一条评论,我现在看到您将promise 变量链接到前一个变量。但是回调函数中的counter 变量仍然存在问题。当回调发生时,它将等于limit @Barmar 当您链接多个 then 时,每个 then 都等待 prev then 解决,并且您作为链的返回值获得的承诺始终是 last then 返回的承诺 知道了,我只是复制了他给的代码,没有考虑循环:D,更新了代码【参考方案2】:

.then 中的函数应该返回一个 Promise。假设 thirdStep 确实返回了一个 Promise,您可以随时将其返回值添加到一个数组中,然后使用 Promise.all 确保它们都已解决。

.then(function(data) 
    var counter = 0;
    var limit = 3;
    var returns = [];
    while(counter<limit)
        returns.push(thirdStep(data.transaction[counter]));
        counter++;
    
    return Promise.all(returns);
)

【讨论】:

这个变体看起来不错,但有一个问题:experssion returns.push(thirdStep(data)) 在所有调用中使用数据对象的最后一个值,但我需要使用这个参数及其每次迭代都有自己的价值。我能解决这个问题吗? @ОлегСидоров 您正在从data 是其参数的函数中调用thirdStep,并且您不会在其中的任何位置更改data。我不确定你想表达什么。 我的例子非常简单。事实上,我需要多次调用thirdStep,每次都在参数中使用新值。

以上是关于JS/jQuery 承诺的主要内容,如果未能解决你的问题,请参考以下文章

js引用jquery问题

jQuery表单验证插件——jquery.validate.js

jquery下载得到两个文件用哪个jquery-2.0.0.js,jquery-2.0.0.min.js

jquery滚动锚点 需要引用哪些js

jquery文件加载出错问题,js调用问题

js JQUERY