通过承诺$q angularjs接收不完整的数据

Receiving incomplete data through promise $q angularjs

本文关键字:数据 承诺 angularjs      更新时间:2023-09-26
当我

控制台记录具有 3 个主要元素的对象时,我期望获得的数据有变化,并显示消息:

HERE ARE THE VARIATIONS IN THE ARRAYS , then the results are:
Object {usr: Object, cat: Array[2], exp: Array[2]} // Incomplete data
Object {usr: Object, cat: Array[3], exp: Array[3]} // complete data

我使用 DexieJS 库从索引数据库获取此数据。我有一个函数,它调用 3 个函数来获取所有数据,即 usr、cat、exp。缺少猫和exp函数中的数据。我的猜测是使用坏承诺的缺失。这就是获取 cat 数据的原因(exp 与更改名称几乎相同):

regresarCat: function () {
        var deferred = $q.defer();
        var cats = [];
        var count = 0;
        db.transaction("rw", db.categories, function () {
            db.categories.orderBy('nameCat').each(function (cat) {
                cats[count] = cat;
                count++;
                deferred.resolve(cats);
            });
        }).catch (function (e) {
            deferred.reject(e);
        });
        return deferred.promise;
    }

获取所有数据函数(regresarTodo)是下一个:

regresarTodo: function(){
var deferred = $q.defer();
var todo = [];
this.regresarUsr().then(function(user){
    todo['usr'] = user;
    deferred.resolve(todo);
    return deferred.promise;
}).catch(function(e) {
    deferred.reject(e)
});
this.regresarCat().then(function(cate){
    todo['cat'] = cate;
    deferred.resolve(todo);
    return deferred.promise;
}).catch(function(e) {
    deferred.reject(e)
});
this.regresarExp().then(function(exps){
    todo['exp'] = exps;
    deferred.resolve(todo);
    return deferred.promise;
}).catch(function(e) {
    deferred.reject(e)
});
$q.all({ usr: this.regresarUsr(), cat: this.regresarCat(), exp: this.regresarExp() }).then(function(respuesta){
    console.log('Got promise');
    console.log(respuesta);
    deferred.resolve(respuesta);
});
return deferred.promise;
}

找不到我的错误,我看到了这些变化,因为我正在调用带有间隔的 regresarTodo 函数,我看到第一次并不总是完整的,有时第二次打印是完整的,但保留了变化。我需要在第一时间获取所有数据。我很迷茫,谢谢

您在.each()处理程序中具有deferred.resolve(cats),但承诺不应多次resolve()

您正在使用的库提供了一种.toArray()方法,因此您应该使用它。

您也不需要使用延迟对象从头开始创建承诺; .toArray()db.transaction()为您创造承诺:

regresarCat: function () {
    return db.transaction("rw", db.categories, function () {
        return db.categories.orderBy('nameCat').toArray();
    });
}

请注意,这也使您的函数缩短了大约 70%。<小时 />您在第二个代码示例中遇到了类似的问题。您正在尝试在三个不同的位置解析单个deferred,而您根本不需要在此处使用延迟。您可以将您的承诺直接传递给$q.all()

regresarTodo: function() {
    return $q.all([this.regresarUsr(), this.regresarCat(), this.regresarExp()])
    .then(function(respuesta){
        console.log('Got values');
        console.log(respuesta);
        return { usr: respuesta[0], cat: respuesta[1], exp: respuesta[2] };
    });
}

再次注意这如何使您的代码缩短约 80%。另请注意,$q.all()参数应为数组

对于每个调用,您基本上需要一个不同的延迟对象。并且您需要在收到来自该调用的数据后解决相应的延迟。

然后随后用上述所有延迟对象的承诺形成一个数组,并在

$q.all(allPromisesArray).then(function(){
    /* your stuff here */
})