Обещание AngularJS возвращает пустую договоренность

В хороший день, я работаю с чтением файлов XML стороны клиента, которые я посылаю в функцию, расположенную в услуге AngularJS, и этот, закончив читать Ваш контент, возвращает мне объект файла и в свою очередь функция, показанная далее добавляет ответ на коллекцию объектов.

Однако в success вызова в $scope.fillCFDIArray() я стараюсь печатать результат, но у меня появляется в консоли такая недействительная договоренность как этот Array[]... но в clicar в да, что содержит объекты, это что-то смущенное, так как я нуждаюсь в том, чтобы пробежать последованную договоренность, но были пустым цикл for просто не входит.

    $scope.fillCFDIArray = function () {
        var deferred = $q.defer();
        var result = [];
        for (var i = 0; i < $scope.filesXML.length; i++) {
            $funcs.readXMLFile($scope.filesXML[i]).then(function successCallBack(response) {
                result.push(response);
            }, function errorCallBack(response) {
                console.log(response);
                deferred.reject(response);
                return deferred.promise;
            });
            if (i == $scope.filesXML.length - 1) {
                deferred.resolve(result);
                return deferred.promise;
            };
        };
    };

        $scope.fillCFDIArray().then(function successCallback(response) {
            console.log(response);//Esta linea en el debug del navegador me aparece Array[]
            for (var i = 0; i < response.length; i++) {
                console.log(response[i]);//Nunca entra aqui puesto que interpreta que el 
//arreglo esta vacio; pero si le doy clic en el 
//debug de firefox sí me aparecen los elementos de ese arreglo
            };
        }, function errorCallBack(response) {
            console.log(response);
        });

Если у кого-то есть идея о том, за чем оно последует, он ему был бы благодарен за Ваши комментарии.

UPDATE

Я добавляю функцию, ответственную читать файл, которая у меня есть внутри услуги AngularJS:

this.readXMLFile = function (file) {
    var deferred = $q.defer();
    if (file) {
        var reader = new FileReader();
        reader.onload = function (element) {
            var xmlText = element.target.result;
            var xml2Json = new X2JS();
            var jsonObj = xml2Json.xml_str2json(xmlText);
            var comprobante = {};
            comprobante = jsonObj.Comprobante;
            deferred.resolve(comprobante);
        };
        reader.readAsText(file);
    } else {
        deferred.reject('El archivo no pudo ser procesado');
    };
    return deferred.promise;
};

Предполагается, что, что он это возвращает, это объект JSON, созданный начиная с контента XML, который читается. Поскольку я читаю файлы с неудара в лунку file многообразно, я должен надеяться, что все отборные файлы обработаны, и тогда возвращать Договоренность, которая содержит объекты, созданные начиная с каждого из начитанных файлов.

Все было в порядке до тех пор, пока я не открыл, что он возвращает мне пустую договоренность.

1
задан 01.11.2016, 18:31
2 ответа

Твоя функция содержит что-то как это в начало

$scope.fillCFDIArray = function () {
    var deferred = $q.defer();

что является ясным строительством обещания.

Это всегда подразумевает, что последняя линия твоей функции должна быть

    return deferred.promise;
}

В твоем случае эта внутри одного if который в Ваш ты видишь, внутри цикла for

for (var i = 0; i < $scope.filesXML.length; i++) {
    // ....
    if (i == $scope.filesXML.length - 1) {
        // ....
        return deferred.promise;
    };
};

В самом деле эта линия находится несколько раз в твоем коде, что ошибка.

Всегда должен будь быть что-то как

function devuelvePromesa() {
    var deferred = $q.defer();

    // ejecuta deferred.reject y deferred.resolve en algún lugar aquí

    return deferred.promise;
}

UPDATE

Если моя интуиция не бьет козырем мне функцию $funcs.readXMLFile, которую ты не включаешь в твой вопрос, возвращает также обещание а следовательно ты падаешь к антиглавному файлу ясного строительства. Есть лучшее решение твоей проблемы, возвращается q.all и объедини все твои обещания в одной.

$scope.fillCFDIArray = function () {
    var promesas = $scope.filesXML.map(function(file) {
        return $funcs.readXMLFile(file);
    });
    return $q.all(promesas);
};

Также ты не был бы должен использовать .then(function, function), немного, как ésto он будет способствовать тому, чтобы твой код не удался

promise.then(function() {
    throw new Error();
}, function() {
    // El callback nunca se ejecutará
});

Всегда используй catch

promise.then(function() {
    throw new Error();
}).catch(function() {
    // El callback manejará el error apropiadamente
});

Читает антиглавный файл .then (success, fail)

3
ответ дан 24.11.2019, 12:50
  • 1
    Спасибо за твой ответ я помогаю мне располагать в порядке лучшей формы функцию. –  KikinRdz 31.10.2016, 21:00
  • 2
    @KikinRdz Твой получающий ответ - antipatr и # 243; n. НИКОГДА ты не должен перемещать обещание из-за пары и # 225; метры, в Вашем месте всегда ты должен делать, что призыв к funci и # 243; n возвратил обещание. Это s и # 243; проводит в callback hell , который для того, что promises были созданы. Я верю в то, что в твоем случае быть должным и # 237; эксперт refactorizar каждые ты c и # 243; я говорю, что, чтобы использовать q.all, он смотрит мой update. Только ты должен строить ясно обещания, когда действительно у тебя не остается другое средство защиты –  devconcept 01.11.2016, 15:36
  • 3
    Спасибо @devconcept, читать и # 233; статья, которую ты комментируешь, чтобы понимать лучше управление обещаний. –  KikinRdz 01.11.2016, 18:35
  • 4
    единственное желание быть благодарное снова @devconcept - невероятно поскольку что-то такое простое кажется таким сложным до тех пор, пока кто-то не осветляет твой взгляд на вещи, я не знаю, если у тебя есть курсы в сети, но если это не так, ты это был бы должен считать, что он ощущается, что у тебя есть много опыта в языке. Приветствие с Мексики –  KikinRdz 02.11.2016, 19:05

SegГєn я вижу, у тебя есть проблема контроля асинхронной разгрузки. а именно, ты не ждешь ответ перед тем, как относиться к обрабатывать результаты. эта ошибка - comГєn очень, когда он занимается с javascript и с обещаниями. я буду объяснять тебе используя твой код:

$scope.fillCFDIArray = function () {
        var deferred = $q.defer();
        var result = [];
        for (var i = 0; i < $scope.filesXML.length; i++) {
// Aquí lees el archivo xml en la posición i, pero es una llamado a una función y tiene una promesa, por lo tanto el for no se detiene, el continua.
            $funcs.readXMLFile($scope.filesXML[i]).then(function successCallBack(response) {
                result.push(response);
            }, function errorCallBack(response) {
                console.log(response);
                deferred.reject(response);
                return deferred.promise;
            });
// Aquí validas si el for ya terminó de ejecutarse, PERO!!! esto no asegura que todas las promesas generadas para la lectura del XML ya terminaron... entonces aquí radica el problema. porque el for es mucho mas rapido que la lectura del XML y cuando llega a este punto el array "result" sigue vacio.
            if (i == $scope.filesXML.length - 1) {
                deferred.resolve(result);
                return deferred.promise;
            };
        };
    };

, когда ты это проверяешь с debug firefox, все кажется нормальным... она razГіn состоит в том, что в этом моменте все обещания уже были решены.

Я рекомендую тебе использовать одну funciГіn переиталик. так ты убеждаешься чтения siguente линии только, когда уже обрабатывается настоящая линия. что-либо подобное:

 // promise: promesa.
// result: el array que quieres llenar.
// pos: posición de lectura del XML,
// xml: xml para lees
function readXML(promise, result, pos, xml){

     // validas si ya terminó de recorrer el XML y resuelves las promesa.
    if(result.length >= pos){
        promise(resolve(result));
        return;
    }
    // procesas la posicion "pos" del xml
    $funcs.readXMLFile($scope.filesXML[i]).then(function successCallBack(response) {
        result.push(response);
        // solo cuando se procesó la liea, vuelves a llamar la misma funcion de forma recursiva con incremento en la posición.
        pos++;
        readXml(promise, result, pos, xml);
    }, function errorCallBack(response) {
        // si hay error, llamas al reject de la promesa y no hay mas llamados recursivos.
        promise.reject(result);
    });

}

, Чтобы называть в нее funciГіn первую, ты видишь:

var promise = $q.defer();
var result = [];
// llamas a la funcion con los valores iniciales.
readXml(promise, result, 0, $scope.filesXML);

// luego defines la respuesta de la promesa.
promise.hen(function(res){
    // .. aquí haces lo que necesitas.
}, function(err){
    //. ocurrío un error en proceso.
})

я обычно не использую обещания для этих случаев, мне нравятся больше callbacks. (для этих случаев) Однако я сделал тебе упражнение с обещаниями.

я это не протестировал, безопасный у меня есть какие-то ошибки, но querГ, - когда форма обучается, как ты был бы должен осуществлять это.

типов Привета.

1
ответ дан 24.11.2019, 12:50
  • 1
    С какими-то соответствиями utilic и # 233; этот ответ, чтобы решать проблему. Я благодарен за опору обоих ответов, но и за #233; sta в особенности он помогает мне с деталью, которую имей, и # 237; в. –  KikinRdz 31.10.2016, 21:35

Теги

Похожие вопросы