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 承诺的主要内容,如果未能解决你的问题,请参考以下文章
jQuery表单验证插件——jquery.validate.js