繁体   English   中英

在JavaScript中按顺序加载AJAX集合

Load AJAX collections in order in JavaScript

提示:本站收集StackOverFlow近2千万问答,支持中英文搜索,鼠标放在语句上弹窗显示对应的参考中文或英文, 本站还提供   中文繁体   英文版本   中英对照 版本,有任何建议请联系yoyou2525@163.com。

如何在JavaScript(jquery)中确保按顺序依次执行某些操作。

说,我需要在加载teachers之前先加载schools集合,以便myTeacher.SchoolName = schools[myTeacher.SchoolId].name;

伪代码如下:

const studentsUrl='api/students', teachersUrl='api/teachers', schoolsUrl='api/schools';
let students = null, teachers = null, schools = null;

$(document).ready(function () {
    getSchools(); 
    getTeachers(); 
    getStudents(); 
});

function getSchools() {
    $.get(schoolsUrl, function (data) {
            window.schools = data;
        });
}

function getTeachers() {
    $.get(teachersUrl, function (data) {
            window.teachers = data;

            // >>> SHOULD BE SURE, SCHOOLS already loaded!!!
            $.each(teachers, function (key, item) {
                item.school = schools[item.schoolId].name;
            });
        });
}

function getStudents() {
    $.get(studentsUrl, function (data) {
            window.students = data;

            // >>> SHOULD BE SURE, TEACEHRS already loaded!!!
            $.each(students, function (key, item) {
                item.teacher = teachers[item.teacherId].name;
            });
        });
}

PS。

还有另一种方法来确保顺序,但在另一个函数的末尾封装一个函数吗?

6 个回复

由于您只需要所有可用的结果,并且每个请求都不依赖于先前的请求,因此可以使用jQuery.when

let students = null;
let teachers = null;
let schools = null;

$(document).ready(function() {
  $.when(
      getSchools(),
      getTeachers()
  ).done(function(shoolResults, teacherResults) {
      window.schools = shoolResults;
      window.teachers = teacherResults;
      handleTeachers();
      getStudents();
  });


  function getSchools() {
    return $.ajax({
      type: 'GET',
      url: schoolsUrl
    });
  }

  function getTeachers() {
    return $.ajax({
      type: 'GET',
      url: teachersUrl
    });
  }

  function handleTeachers() {
   $.each(teachers, function (key, item) { 
     item.school = schools[item.schoolId].name;
    });
  }
});

正如其他人已经建议的那样,您可以链接请求。 我对您的代码进行了一些更改。

  1. 添加了严格模式 ,有助于防止错误
  2. IFFE中包装了该代码,以防止全球污染

如果所有api都属于同一服务器,则可以在服务器端处理所有这些数据并返回一个已填充的json。 这样,您的服务器将在构造此json上做一些额外的工作,但另一方面,您将只发出一个ajax请求而不是3。这将更快地工作,并且可以将json缓存一段时间

第一个解决方案的代码

(function () {

'use strict';
const studentsUrl = 'api/students';
const teachersUrl = 'api/teachers';
const schoolsUrl = 'api/schools';

let students = null;
let teachers = null;
let schools = null;

var scoolData = {
    schools: null,
    teachers: null,
    students: null
};

$(document).ready(function () {
    getSchools().then(function (schools) {
        scoolData.schools = schools;
        getTeachers().then(function (teachers) {
            scoolData.teachers = teachers;
            $.each(scoolData.teachers, function (key, item) {
                item.school = scoolData.schools[item.schoolId].name;
            });
        });
    });
});

function getSchools() {
    return $.get(schoolsUrl);
}

function getTeachers() {
    return $.get(teachersUrl,
        function (result) {
            scoolData.teachers = result;

            // >>> SHOULD BE SURE, SCHOOLS already loaded!!!
            $.each(teachers, function (key, item) {
                item.school = scoolData.schools[item.schoolId].name;
            });
        });
}
})();

如果您希望他们按顺序排列(尽管我不确定我为什么会这样,因为您无论如何都会检索所有的学校/老师/学生),只需执行此操作即可。

注意 :在以下示例中, get*函数是虚拟变量。 相反,只需返回来自它们的$.get调用的结果:

 function getSchools() { return Promise.resolve({1: {name: 'school1'}}); } function getTeachers() { return Promise.resolve({1: {name: 'teacher1', schoolId: 1}}); } function getStudents() { return Promise.resolve({1: {name: 'student1', teacherId: 1}}); } (async () => { const schools = await getSchools(); const teachers = await getTeachers(); const students = await getStudents(); // Alternative for the $.each code Object.values(teachers).forEach(teacher => teacher.school = schools[teacher.schoolId].name); Object.values(students).forEach(student => student.teacher = teachers[student.teacherId].name); console.log(schools, teachers, students); })(); 

另一个注意事项:这是ES8代码,如果您需要支持较旧的浏览器并且不能使用像Babel这样的编译器,我将发布一个非异步/等待版本。

不依赖于ES8的代码

 function getSchools() { return Promise.resolve({1: {name: 'school1'}}); } function getTeachers() { return Promise.resolve({1: {name: 'teacher1', schoolId: 1}}); } function getStudents() { return Promise.resolve({1: {name: 'student1', teacherId: 1}}); } let schools = null, teachers = null, students = null; getSchools().then(_schools => { schools = _schools; return getTeachers(); }).then(_teachers => { teachers = _teachers; return getStudents(); }).then(_students => { students = _students; for (var _ in teachers) { teachers[_].school = schools[teachers[_].schoolId].name; } for (var _ in students) { students[_].teacher = teachers[students[_].teacherId].name } console.log(schools, teachers, students); }); 

调用getTeachers(); getSchools(); 返回成功或完成,成功是首选,因为如果有错误,则运行完整。

我认为您正在寻找这个。

 getSchools().done(function(data){
      var someId = data.findThatId;
      getTeachers(someId);
 }); 

您将需要从Ajax调用返回的数据获得datadone

您可以异步加载它们,但必须等到两个调用完成。

为此,请在ajax调用之前添加return并将结果合并到ready函数中(而不是在教师调用的成功处理程序中):

let schoolsPromise = getSchools();
let teachersPromise = getTeachers();
$.when(schoolsPromise, teachersPromise)
  .then((schools, teachers) => {
    $.each(teachers, (key, item) => {
      item.school = schools[item.schoolId].name;
    });
  });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题
 
粤ICP备18138465号  © 2020-2022 STACKOOM.COM