当我调用第二个在AWS中调用脚本并正在等待AWS响应的函数时,如何在.each循环中进行迭代等待? 这是我的.each循环:
$('.subscriptionStatus').each(function(i, obj) {
var sku = $(this).attr('data-sku');
subscriptionStatus(sku, function(response) {
var messageDiv = $(this).closest('.subscriptionMessage');
var innerHtml = '';
if (response){
innerHtml = 'Successful';
}else{
innerHtml = 'Failed';
}
messageDiv.html(innerHtml);
}//wait until
}
对于每次迭代,我正在调用一个函数,在我调用AWS Lambda中的脚本时需要等待其响应,然后继续迭代:
function subscriptionStatus( sku, callback ){
var lambda = new AWS.Lambda();
lambda.invoke({
FunctionName: 'MyFunction',
Payload: JSON.stringify({
"sku":sku
})
}, function(err, data){
//response from AWS Lambda
var success = data.Payload;
if( success == 'true'){
//NEED TO PASS TRUE BACK TO THE CURRENT ITERATION OF THE EACH LOOP
callback(true); //correct way?
}else{
//NEED TO PASS FALSE BACK TO THE CURRENT ITERATION OF THE EACH LOOP
callback(false); //correct way?
}
});
}
我的问题是迭代没有等待。
我的代码有什么问题?
答案 0 :(得分:1)
最简单的方法是使用Promises和Deferreds(在jQuery中)
你的代码大致是:
function subscriptionStatus( sku ){
var $dfd = jQuery.Deferred();
var lambda = new AWS.Lambda();
lambda.invoke({
FunctionName: 'MyFunction',
Payload: JSON.stringify({
"sku":sku
})
}, function(err, data){
if( data.Payload == 'true'){
$dfd.resolve();
}else{
$dfd.reject();
}
});
return $dfd.promise();
}
你现在可以做到:
subscriptionStatus(<sku>)
.done(function() {
}).fail(function() {
});
现在看看这个花哨的部分:如何在你的.each循环中实现它?这取决于它是否需要以正确的顺序或者你必须等到它们全部完成。如果你只是等待所有这些都没有按顺序完成:
// no particular order
var deferreds = []; // does nothing yet
$('.bla').each(function(){
var $this = $(this);
var $msgDiv = $this.closest('.subscriptionMessage');
var sku = $this.attr('data-sku');
var $dfd = subscriptionStatus(sku)
.done(function() { $msgDiv.html('Successful'); })
.fail(function() { $msgDiv.html('Failed'); });
deferreds.push($dfd);
});
jQuery.when.apply(jQuery,deferreds)
.done(function() { alert('all successful'); })
.fail(function() { alert('any of the requests was not succesful'); })
.always(function() { alert('they are all done'); });
答案 1 :(得分:0)
你有没有得到这个工作?我发现您的代码中的另一个问题与Lambda没有任何关系。您传递给subscriptionStatus的回调中this
的值不会是.subscriptionStatus
元素。所以最有可能messageDiv
始终是一个空的jQuery对象。您可以将其注销以进行验证。
要解决此问题,请在this
中保存对.each()
的引用,如下所示:
$('.subscriptionStatus').each(function(i, obj) {
var _this = $(this); // save reference
var sku = _this.attr('data-sku');
subscriptionStatus(sku, function(response) {
// now _this has a reference to the actual jQuery object wrapping the .subscriptionStatus element
var messageDiv = _this.closest('.subscriptionMessage');
var innerHtml = '';
if (response){
innerHtml = 'Successful';
}else{
innerHtml = 'Failed';
}
messageDiv.html(innerHtml);
}//wait until
}
我怀疑这会解决你的问题,除非你真的想要阻止,直到每个响应都回来(这将损害渲染时间)。如果是这样的话,你应该看看Promises。