简体   繁体   中英

Nested promise in TypeScript and Angular 2

I have this method fallbackToLocalDBfileOrLocalStorageDB which return a promise and calls another method getDBfileXHR which also is a promise.

In this code, I would like to know it I have to use 'resolve()' or if resolving getDBfileXHR will automatically resolve fallbackToLocalDBfileOrLocalStorageDB ?

As you can see I commented the then().catch() parts, but I don't know if I have to leave them or not.

fallbackToLocalDBfileOrLocalStorageDB() {
        return new Promise(function (resolve, reject) {
            if (this.storageService.get('prodata') === null) { 
                if (this.connectionStatus.f() !== 'online') {
                } else {
                    this.sendErrorEmail("BL: online but falling back to local proDB", 10);
                }
                console.log('...falling back to local proBD.jsonp.');
                return this.getDBfileXHR('proDB.jsonp');
                    // .then(function () {
                    //    console.log('...falling back to local proBD.jsonp succeeded.');
                    //    resolve();
                    // })
                    // .catch(, function () {
                    //    console.log('...error, shit.');
                    //    reject();
                    // });

EDIT showing the full nested functions, with partially fixed code:

import { Injectable } from '@angular/core';
...

export class UpdateProDB {

    constructor(
        ) {
    }   


    get() {
        var debugOptionUseLocalDB = 0,
        prodata = [],
        serverAttempts = 0;     return new Promise((resolve, reject) => {
            if (debugOptionUseLocalDB) {
                return this.fallbackToLocalDBfileOrLocalStorageDB();
            }
            if (this.connectionStatus.f() === 'online') {
                console.log("Fetching DB from the server:");
                return this.getDBfileXHR(this.dbUrl(), serverAttempts)
                .then(function (data) { 
                    console.log('-normal XHR request succeeded.');

                    resolve(data);
                })
                .catch((reason)=> {
                    if (typeof serverAttempts !== "undefined") serverAttempts++;
                    console.log('on passe dans le catch, serverAttempts = ', serverAttempts)
                    if (serverAttempts < 2) {
                        return this.getDBfileXHR(this.dbUrl(), serverAttempts)
                        .then(function () { 
                            console.log('-basic XHR request succeeded.');

                        })
                        .catch(function (){
                            console.log("-basic XHR request failed, falling back to local DB file or localStorage DB...");

                        })
                    } else {
                        console.log("-basic XHR request failed, falling back to local DB file or localStorage DB...");
                        return this.fallbackToLocalDBfileOrLocalStorageDB()
                        .then((data)=>{
                            resolve(data);
                        })
                        .catch((reason)=> {
                            reject(reason);
                        });
                    }
                });
            });
    }   

    getDBfileXHR(url, serverAttempts) {
        return new Promise((resolve, reject) => {
            var request = new XMLHttpRequest();
            request.open("GET", url, true);             
            request.onload = ()=> {
                if ( (request.readyState === 4) && ( (request.status >= 200 && request.status <= 299) || request.status === 304 || request.status === 0) ) {
                    console.log('-we get response '+request.status+' from XHR in getDBfileXHR');

                    var jsonText = request.responseText.replace("callback(", "").replace(");", ""); 

                    if (jsonText === '') {
                        console.error('-error');

                        reject({
                            status: request.status,
                            statusText: request.statusText
                        });

                    } else {
                        var parsedJson;
                        try {
                            parsedJson = JSON.parse(jsonText);
                        } catch (e) {
                            resolve(request.response);
                        }
                    }
                };
                request.onerror = ()=> {
                    reject({
                        status: request.status,
                        statusText: request.statusText
                    });
                };
                console.log("sending request.send()");
                request.send();

            });
    }   


    fallbackToLocalDBfileOrLocalStorageDB() {
        return new Promise((resolve, reject) => {
            if (this.storageService.get('prodata') === null) { 
                if (this.connectionStatus.f() !== 'online') {

                } else {
                    this.sendErrorEmail("BL: online but falling back to local proDB", 10);
                }
                console.log('...falling back to local proBD.jsonp.');
                return this.getDBfileXHR('proDB.jsonp', undefined)
                .then(function (data) {
                    console.log('...falling back to local proBD.jsonp succeeded.');
                    resolve(data);
                })
                .catch((reason)=> {
                    console.log('...error, shit.');
                    reject(reason);
                });
            } else { 
                resolve();
            }
        });
    }   

first use arrow function => instead of function to preserve this keyword:

fallbackToLocalDBfileOrLocalStorageDB() {
        return new Promise((resolve, reject) => {
            if (this.storageService.get('prodata') === null) { 
                if (this.connectionStatus.f() !== 'online') {
                } else {
                    this.sendErrorEmail("BL: online but falling back to local proDB", 10);
                }
                console.log('...falling back to local proBD.jsonp.');
                return this.getDBfileXHR('proDB.jsonp');
                      .then(function (data) {
                         console.log('...falling back to local proBD.jsonp succeeded.');
                        resolve(data);
                     })
                      .catch((reason)=> {
                         console.log('...error, shit.');
                        reject(reason);
                      });

and yu can access you data like this :

fallbackToLocalDBfileOrLocalStorageDB().then((data)=>{
   console.log(data);
})

The argument to the new Promise() is called an executor function. It needs to either resolve() or reject() the promise.

What you are trying to do is to return another Promise from that executor function. According to MDN , "The return value of the executor is ignored."

This means that the way you're trying to use this inner Promise won't work, and you must explicitly resolve or reject like you're doing in your commented code.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM