Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript jQuery延迟请求和承诺:如何嵌套并发异步调用_Javascript_Jquery - Fatal编程技术网

Javascript jQuery延迟请求和承诺:如何嵌套并发异步调用

Javascript jQuery延迟请求和承诺:如何嵌套并发异步调用,javascript,jquery,Javascript,Jquery,我的情况如下: 我需要保存一个包含学生数据的数组。 每个学生都有两个嵌套的第一年和第二年的分数数组 我的目标是异步保存每个学生的数据-但在完成此过程并显示添加的学生数量之前,我需要为每个学生保存第一年和第二年的分数数据。此数据也以异步方式保存 我目前的问题是,学生记录被保存,而第一年和第二年的成绩仍在处理中。 第1年和第2年的成绩数据必须异步保存,因为它们之间没有相关性。但是,当我准备显示添加的学生人数时,所有数据都应该保存。 我还必须说,第一年和第二年的成绩数据取决于新的学生id 如何使用jQ

我的情况如下:

我需要保存一个包含学生数据的数组。 每个学生都有两个嵌套的第一年和第二年的分数数组

我的目标是异步保存每个学生的数据-但在完成此过程并显示添加的学生数量之前,我需要为每个学生保存第一年和第二年的分数数据。此数据也以异步方式保存

我目前的问题是,学生记录被保存,而第一年和第二年的成绩仍在处理中。 第1年和第2年的成绩数据必须异步保存,因为它们之间没有相关性。但是,当我准备显示添加的学生人数时,所有数据都应该保存。 我还必须说,第一年和第二年的成绩数据取决于新的学生id

如何使用jQuery承诺实现这一点?如果您运行下面的JSFIDLE,您将看到输入的记录数显示在分数年数据显示之前,而它应该是相反的。输入的学生总数的显示应取决于分数年任务的完成情况。另外,我对同步保存学生记录不感兴趣

代码如下:(在JSFIDLE中运行代码)

函数性能更新(){
var arr_Promissions=[];
var学生=[
{
id:1,姓名:“约翰”,成绩EAR1:[{科目:“数学”,成绩:8},
{科目:化学,成绩:7}],成绩EAR2:[{科目:数学,成绩:9},{科目:化学,成绩:8}]
},
{
id:2,姓名:“玛丽”,成绩EAR1:[{科目:“数学”,成绩:9},
{科目:化学,分数:8}],分数EAR2:[{科目:数学,分数:10},{科目:化学,分数:7}]
}
];
$。每个(学生,函数(索引,学生){
arr_promises.push(SaveStudent(student));
});
$.when.apply($,arr_promissions).done(函数(){
var msg='添加的学生总数:'+arguments.length+'

'; $(“div”)。追加(msg); }); }; 函数SaveStudent(学生){ var dfrd=$.Deferred(); executeQueryAsync(学生, 函数(){ 风险价值年数=[]; //第一年保存分数 $.each(student.scoresYear1,函数(索引,分数){ executeQueryAsync(分数, 函数(){ 推送({status:true}); }, 函数(发送方,参数){ 警报(“请求失败”); }); }); //第二年保存分数 $.each(student.scoresYear2,函数(索引,分数){ executeQueryAsync(分数, 函数(){ 推送({status:true}); }, 函数(发送方,参数){ 警报(“请求失败”); }); }); $.when.apply($,arrscoreers).done(函数(){ //console.log('added score year 1-Subject:'+score.Subject+'对于学生:'+student.name)); var msg='为学生增加了分数年:'+student.name+'

'; $(“div”)。追加(msg); }).然后(函数(){ 解析({status:true}); });; }, //失败 函数(发送方,参数){ 警报(“请求失败”); }); }//学生节结束 函数executeQueryAsync(student、callbackSuccess、CallbackMail){ //模拟服务器调用 setTimeout(函数(){ callbackSuccess({status:true}); }, 3000) }
如果您想使用
$。当
时,您必须将一个或多个延迟对象传递给它-至少如果您想何时具有任何意义。如果未将任何延迟对象传递给
$。当
时,它将立即执行。由于
SaveStudent
不返回值,因此您正在向
$馈送一个空数组。当
-时,您的“已添加的学生总数:…”消息几乎会立即追加

(如果你不相信我,看看这把小提琴:)

因此SaveStudent需要返回一个延迟对象:

function SaveStudent(student) {
    var dfrd = $.Deferred();
    /* other SaveStudent stuff */

    return dfrd;
}
这样做之后,你发现这个改变“没有什么不同”。这几乎是正确的。这是因为
dfrd
几乎立即得到解决,原因与上面解释的基本相同<当
arrScoreYears
中的所有延迟对象都已解决时,code>dfrd
将得到解决,但
arrScoreYears
中没有延迟对象,因此
dfrd
将立即得到解决

因此,让我们将延迟添加到
arrscoreers
。出于干燥的考虑,我将创建一个函数来实现这一点,这样我们就不用重写相同的代码来保存第一年和第二年的分数:

var saveYearScores = function (year_scores, deferreds) {
    $.each(year_scores, function (index, score) {
        var deferred = $.Deferred();
        deferreds.push(deferred);     
        executeQueryAsync(score,
            function () {
                deferred.resolve();
             },
             function (sender, args) {
                 deferred.fail();
                 alert('Request failed.');
             });
     });
};
请注意,我们为异步保存的每一年创建一个延迟分数。我选择将包含延迟的数组传递到函数中,以便它可以将新的延迟对象附加到数组中。重要的是,对于每个调用
SaveStudent
,我们都有一个延迟对象数组,每个对象表示一个异步save score调用

现在,我们可以将
SaveStudent
中的每个调用替换为对新函数的调用:

saveYearScores(student.scoresYear1, arrScoreYears);
saveYearScores(student.scoresYear2, arrScoreYears);
现在,
$。当
调用实际上将等待我们的save score调用完成

我已经更新了你的小提琴:

在myContext.executeQueryAsync行之前,我都能理解事情。保存学生时是否从服务器返回学生id?是。执行myContext.executeQueryAsyn后,您可以提取学生id,该id将用于添加分数EAR1/2记录。这在第var newid=newStudent.get_id()行中显示;第一个o
saveYearScores(student.scoresYear1, arrScoreYears);
saveYearScores(student.scoresYear2, arrScoreYears);