执行两次承诺时'Cannot read property of undefined'



现在我正在与承诺一起面对异步问题。事情是,当我第一次执行承诺时,它工作得很好。但是当我两次执行相同的函数时,会出现"无法读取未定义的属性"。重新加载页面可以解决问题,但并不是用户每次都刷新的想法。

所以我想知道为什么会这样。之前的承诺还在运行?如果是这样,如何重置或刷新它?

我使用打字稿和角度 4。

这是错误:

TypeError: Cannot read property 'ensenanza' of undefined
    at SafeSubscriber._next (notas.service.ts:87)
    at SafeSubscriber.webpackJsonp.../../../../rxjs/Subscriber.js.SafeSubscriber.__tryOrSetError (Subscriber.js:248)
    at SafeSubscriber.webpackJsonp.../../../../rxjs/Subscriber.js.SafeSubscriber.next (Subscriber.js:188)
    at Subscriber.webpackJsonp.../../../../rxjs/Subscriber.js.Subscriber._next (Subscriber.js:126)
    at Subscriber.webpackJsonp.../../../../rxjs/Subscriber.js.Subscriber.next (Subscriber.js:90)
    at Notification.webpackJsonp.../../../../rxjs/Notification.js.Notification.observe (Notification.js:32)
    at QueueAction.webpackJsonp.../../../../rxjs/operators/observeOn.js.ObserveOnSubscriber.dispatch (observeOn.js:89)
    at QueueAction.webpackJsonp.../../../../rxjs/scheduler/AsyncAction.js.AsyncAction._execute (AsyncAction.js:111)
    at QueueAction.webpackJsonp.../../../../rxjs/scheduler/QueueAction.js.QueueAction.execute (QueueAction.js:33)
    at QueueScheduler.webpackJsonp.../../../../rxjs/scheduler/AsyncScheduler.js.AsyncScheduler.flush (AsyncScheduler.js:36)

以及我正在处理的代码段

asignatura(key) { //obtener x cookie el rbd
        var cod= [];
        var total_listado = [];
        var prom = Promise;
        return prom.resolve(this.datoCurso(this.key)).then( dcurso =>{
            console.log(dcurso);
            this.firebase.list('/sistema/asignaturaRBD').subscribe((asignaturaA) => {
                for (let k = 0; k < asignaturaA.length; k++) {
                    const a = asignaturaA[k];
                    console.log(a.ensenanza +'=='+ dcurso[0].ensenanza +'&&'+ a.nivel +'=='+ dcurso[0].nivel+ '&&'+ a.rbd +'=='+ dcurso[0].rbd);

                    if (a.ensenanza == dcurso[0].ensenanza && a.nivel == dcurso[0].nivel && a.rbd == dcurso[0].rbd) {
                        cod.push({
                            asignatura: a.asignatura,
                            ensenanza: a.ensenanza,
                            nivel: a.nivel})
                            console.log("Paso por if");
                            //total_listado.push({ key: a.$key, asignatura: a.asignatura, ensenanza: a.ensenanza, estado: a.estado, nivel: a.nivel, rbd: a.rbd })
                        }
                    }  
                });
                return this.getNombreAsignatura(cod);
            });
        }

拿督库尔索代码

datoCurso(key) { //get todos los datos x key
            let pushcurso = new Array();
            this.firebase.list('/sistema/curso', {
                query: {
                    equalTo: key,
                    orderByKey: key,
                    limitToFirst: 1
                }
            }).subscribe((datos) => {
                for (let v = 0; v < datos.length; v++) {
                    const c = datos[v];
                    pushcurso.push({
                        ensenanza: c.cod_ensenanza,
                        nivel: c.nivel,
                        rbd: c.rbd
                    });
                    console.log(pushcurso[0].ensenanza+'--'+pushcurso[0].nivel+'--'+pushcurso[0].rbd);
                    // pushcurso = [{nivel: c.nivel, ensenanza: c.cod_ensenanza}];
                }
            });
            return pushcurso;
        }

你在这里不需要承诺。您可以编写datoCurso方法,以便它返回某个对象的可观察量,如下所示:

datoCurso(key)
{
    let pushcurso = new Array();
    this.firebase.list('/sistema/curso', {
        query: {
            equalTo: key,
            orderByKey: key,
            limitToFirst: 1
        }
    }).map((datos: any[]) => datos.map(c => ({
        ensenanza: c.cod_ensenanza,
        nivel: c.nivel,
        rbd: c.rbd
    })));
}

然后,您可以像这样压缩两个可观察量,并对结果执行逻辑:

Observable.zipArray( // or zipAll - depends on rxjs version
    this.datoCurso(this.key),
    this.firebase.list('/sistema/asignaturaRBD')
).subscribe(([dcurso, asignaturaA]: [any[], any[]]) =>
{
    this.getNombreAsignatura(asignaturaA
        .filter(a => a.ensenanza == dcurso[0].ensenanza && a.nivel == dcurso[0].nivel && a.rbd == dcurso[0].rbd)
        .map(a => ({
            asignatura: a.asignatura,
            ensenanza: a.ensenanza,
            nivel: a.nivel
        })));
});

PS:因为我不知道这到底是怎么回事 - 所以不能保证

所以我解决了它。我删除了承诺并设置了超时。

喜欢这个:

asignatura(key) { //obtener x cookie el rbd
        var cod= [];
        var total_listado = [];
        var prom = Promise;
        var dc = this.datoCurso(this.key);
        setTimeout(() => {
        this.firebase.list('/sistema/asignaturaRBD').subscribe((asignaturaA) => {
                for (let k = 0; k < asignaturaA.length; k++) {
                    const a = asignaturaA[k];
                    if (a.ensenanza == dc[0].ensenanza && a.nivel == dc[0].nivel && a.rbd == dc[0].rbd) {
                        cod.push({
                            asignatura: a.asignatura,
                            ensenanza: a.ensenanza,
                            nivel: a.nivel})
                            console.log("Paso por if");
                            //total_listado.push({ key: a.$key, asignatura: a.asignatura, ensenanza: a.ensenanza, estado: a.estado, nivel: a.nivel, rbd: a.rbd })
                        }
                    }  
                });
        }, 3000);
        return this.getNombreAsignatura(cod);
    }

getNombreAsignatura(n){
        var arr = [];
        console.log(n);
        setTimeout(() => {
        this.getAsignatura().subscribe((data)=>{
            for (let i = 0; i < data.length; i++) {
                const asignatura = data[i];
                for (let j = 0; j < n.length; j++) {
                    const cod= n[j];
                    if(asignatura.cod_asignatura == cod.asignatura && asignatura.tipo_ensenanza == cod.ensenanza && asignatura.curso == cod.nivel){
                        arr.push({
                            codigo: asignatura.cod_asignatura,
                            nombre: asignatura.detalle
                        })
                        console.log(asignatura);    
                    }
                }
            }
        });
    }, 5000);
        console.log(arr);
        return arr;
    }

这很奇怪,但有效。

相关内容

最新更新