Angular Promises возвращает q.all() с пустым массивом

Чего я пытаюсь достичь, так это:

  • Вызов моей службы для получения всех встреч в типах встреч (количество типов не фиксировано), привязанных к врачу
  • Если есть 3 типа встреч, то будет сделано 3 асинхронных вызова
  • вернуть одно обещание с помощью $q.all() после того, как все 3 обещания были разрешены

Служба назначения

this.getAllDoctorAppointments = function (doctor, appointmentTypeArray) {

        var promises = [];

        angular.forEach(appointmentTypeArray, function (appointmentType) {

            var defer = $q.defer();

            $http.get('/appointments/?doctorName=' + doctor + '&apptType=' + appointmentType)
                .success(function (listOfAppointments) {

                    defer.resolve(listOfAppointments);
                    promises.push(defer.promise);

                });
        });

        return $q.all(promises);

    };

В моем консольном журнале назначениеType возвращает [ ]. Это происходит из-за того, что пустой массив "promises" возвращается еще до того, как будут сделаны 3 асинхронных вызова. Я все еще очень новичок в концепции обещаний, как лучше всего это сделать? Спасибо!

$scope.getAllDoctorAppointments = function (doctor, appointmentTypeArray) {

    appointmentService.getAllDoctorAppointments(doctor, appointmentTypeArray)

        .then(function (appointmentType) {

//could take in any number. hardcoded 3 just for testing.
console.log(appointmentType)

            angular.forEach(appointmentType[0], function (xRay) {
                $scope.xRayAppts.events.push(xRay);
            });

            angular.forEach(appointmentType[1], function (ctScan) {
                $scope.ctScanAppts.events.push(ctScan);
            });

            angular.forEach(appointmentType[2], function (mri) {
                $scope.mriAppts.events.push(mri);
            });

        });

};

person lemoncode    schedule 14.10.2015    source источник
comment
не нужен var defer, но в то же время он будет работать, если вы не нажмете обещание внутри обратного вызова успеха... слишком поздно тогда.. натолкните его за пределы success   -  person charlietfl    schedule 14.10.2015


Ответы (2)


this.getAllDoctorAppointments = function (doctor, appointmentTypeArray) {
    var promises = [];

    angular.forEach(appointmentTypeArray, function (appointmentType) {

        promises.push($http.get('/appointments/?doctorName=' + doctor + '&apptType=' + appointmentType)
            .success(function (listOfAppointments) {
                return listOfAppointments;
            });
        );
    });

    return $q.all(promises);
};

$http.get возвращает обещания, которые вы хотите собрать, в этом случае нет необходимости в новом отсрочке.

person Icycool    schedule 14.10.2015

обещание не добавляется в массив, потому что код, который добавляет его в массив, promises.push(defer.promise);, находится внутри кода результата того, что вы пытаетесь отложить. Таким образом, обещание не будет добавлено в список обещаний для выполнения до тех пор, пока оно не будет выполнено!

поэтому вы можете либо переместить эту строку push за пределы вызова успеха, выглядя примерно так:

angular.forEach(appointmentTypeArray, function (appointmentType) {

        var defer = $q.defer();

        $http.get('/appointments/?doctorName=' + doctor + '&apptType=' + appointmentType)
            .success(function (listOfAppointments) {

                defer.resolve(listOfAppointments);

            });
        promises.push(defer.promise);

    });

или вы можете сделать, как предлагает lcycool, и просто добавить вызовы $http.get(...).success(...) в массив напрямую.

person Peter Elliott    schedule 14.10.2015