Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angular 强制Javascript/节点等待服务完成_Angular_Typescript - Fatal编程技术网

Angular 强制Javascript/节点等待服务完成

Angular 强制Javascript/节点等待服务完成,angular,typescript,Angular,Typescript,我试图调用一个服务,并用结果值构建一个对象。如果我知道我在做什么,我也会处理错误,但我不知道如何处理。不幸的是,代码开始服务调用,然后在服务调用完成之前返回到服务后面的语句 我不在乎它有多么不现代、不酷或是其他什么,我希望这段代码能等待服务的成功或失败。无论如何,我在应用程序中所做的一切都取决于这项服务的成功 我都尝试设置断点并添加日志语句 import { Injectable, Injector } from '@angular/core'; import { HttpClient, Htt

我试图调用一个服务,并用结果值构建一个对象。如果我知道我在做什么,我也会处理错误,但我不知道如何处理。不幸的是,代码开始服务调用,然后在服务调用完成之前返回到服务后面的语句

我不在乎它有多么不现代、不酷或是其他什么,我希望这段代码能等待服务的成功或失败。无论如何,我在应用程序中所做的一切都取决于这项服务的成功

我都尝试设置断点并添加日志语句

import { Injectable, Injector } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { UUID } from 'angular2-uuid';
import { Constants } from './constants';

@Injectable()
export class AppConfigService {

    private constants = null;

    constructor (private injector: Injector) { }

    loadAppConfig() {
        let http = this.injector.get(HttpClient);
        /*
        return http.get('/assets/app-config.json')
        .toPromise()
        .then(data => {
            this.appConfig = data;
        })
        */
        if(this.constants != null) {
            console.log('@@WOODSMAN environmentData is not null');
            console.log('@@WOODSMAN lazy loaded environmentData already is '+JSON.stringify(this.constants));    
        } else {
            console.log('@@WOODSMAN environmentData is null');   

            let headerValues = new HttpHeaders()
                .set('Accept-Encoding', 'application/json; charset=UTF-8')
                .set('Content-Type', 'application/json; charset=UTF-8')
                .set('SC_TRACE_ID', UUID.UUID());
            let httpOptions = {
                headers: headerValues
            };
            console.log('@@WOODSMAN: Waiting for environment info from service call');

            let appConfig = http.post("/proxy/report/getEnvironment", "",httpOptions)
                .toPromise().then(data => { 
                this.setConstants(data);
            });


/*
            while(this.environmentData == null) {
                console.log('@@@WOODSMAN appConfig is null even after service call');
            }
*/
            if(this.constants == null) {
                console.log('@@@WOODSMAN appConfig is null even after service call');
            }
        };
        console.log('@@WOODSMAN: environmentData result = '+JSON.stringify(this.constants));
    }

    private setConstants(environmentData) {
        console.log('@@WOODSMAN calling environmentData='+JSON.stringify(environmentData));
        this.constants = new (environmentData);
    }

    get config() {
        //return this.appConfig;
        if(this.constants==null) {
            console.log('@@WOODSMAN Call to config found null appConfig.  Calling the load');
            this.loadAppConfig();
            if(this.constants==null) {
                console.log('@@WOODSMAN Second call to config still found null appConfig.');
            }
        }
        console.log('@@WOODSMAN environment.salesconnectURL' + this.constants["baseUrl"]);
        console.log('@@WOODSMAN environment.salesconnectURL' + this.constants["homepageURL"]);
        console.log('@@@WOODSMAN end getConstants ');
        return this.constants;
    }

}
我在浏览器日志中看到这两行的顺序(它们之间没有日志语句)。 “@@WOODSMAN:正在等待来自服务调用的环境信息” “@@@WOODSMAN appConfig即使在服务调用之后也是空的”

我尝试将其包装在一个异步函数中并添加一个wait语句,但它仍然忽略了这一点,并没有等待完成

由于服务需要几毫秒才能完成,因此我尝试在上面添加一个while循环,以等待设置该值。但是,由于不允许服务处理程序满足循环条件,因此它变成了一个永久循环

***更新

我尝试添加一个提供同步功能的查询调用。因此,我编写了以下代码:

            let ajaxObject = {
                type: "POST"
                ,headers: {
                     'Accept-Encoding' : 'application/json; charset=UTF-8'
                    ,'Content-Type' : 'application/json; charset=UTF-8'
                    ,'SC_TRACE_ID' : UUID.UUID()
                }
                ,url: "/proxy/report/getEnvironment"
                ,async : false
                ,data: "" 
                ,success: function(data) {
                    this.status="SUCCESS";
                    this.dataReturned = data;
                    console.log('@@WOODSMAN success reached');
                }
                ,error: function(jqXHR, textStatus, errorThrown) {
                    this.status="FAILURE";
                    this.jqXHR = jqXHR;
                    this.textStatus = textStatus;
                    this.errorThrown = errorThrown;
                    console.log('@@WOODSMAN failure reached');
                    console.log('Error on call to getEnvironment.  '+textStatus+' '+errorThrown);
                }
                ,status: "NOT_RUN"
                ,dataReturned : null
                ,jqXHR: {}
                ,textStatus: {}
                ,errorThrown: {} 
            };
            $.ajax(ajaxObject);
            console.log('@@@WOODSMAN after ajax service call' + JSON.stringify(ajaxObject));
当我运行这个时,我得到了状态为“NOT_run”的“@@@WOODSMAN after ajax服务调用”;这意味着在调用时,它既没有执行成功函数,也没有执行失败函数。请注意,请求具有async:false,set,因此它没有理由执行异步调用


可以用Javascript进行套接字编程吗?很明显,进行同步调用变得异常困难。

您应该知道JS是异步的,意味着任何处理WEB API的代码, 它不会等待它完成,而是会继续执行下一行代码

在您共享的代码段中

let appConfig = http.post("/proxy/report/getEnvironment", "",httpOptions)
                .toPromise().then(data => { 
                this.setConstants(data);
            });
是异步的。因此JS引擎不会等待它完成,它将执行下一行代码。即:

if(this.constants == null) {
                console.log('@@@WOODSMAN appConfig is null even after service call');
            }
由于上述行是在服务调用完成之前执行的,因此
this.constants
此时为
null
。这就是您能够在控制台中看到最后一条语句的原因

要检查
this.constants
是否为
null
,即使在服务调用之后,也可以按如下方式修改代码:

let appConfig = http.post("/proxy/report/getEnvironment", "",httpOptions)
                .toPromise().then(data => { 
                this.setConstants(data);
                if(this.constants == null) {
                console.log('@@@WOODSMAN appConfig is null even after service call');
            }
        });
**更新:

这是实现
async wait
的方法:

public  async loadAppConfig() {
        let http = this.injector.get(HttpClient);

            let appConfig = await http.post("url",{options})
                .toPromise().then(data => { 
                  .... next lines
            });

           console.log('this line will not execute until await is finished');

    } 

这是stackblitz演示:

你是如何调用这个服务的?这是一篇帖子,除此之外,我不知道库是如何实现的。我看到了Javascript在同步/异步方面的不同表现。关于堆栈溢出,我在前面看到了一个这样的链接:。媒体上的另一个人声称,使用toPromise()将可观察到的内容转换为承诺,然后强制它等待完成。其中只有一半似乎是正确的。上面的“如果”测试只是为了证明一点。我需要一些东西,任何东西,可以让我把我所做的事情建立在从服务中获得的价值的基础上。那么你有什么疑问呢?不要不必要地使事情复杂化。无论是可观察的还是承诺的,它们都用于处理异步调用。它们都不会改变JS的行为方式。如果希望在异步调用完成后检查结果,则必须检查内部回调。每个方法都有自己的回调处理机制。我的理解是,您希望逐行串行执行代码。您可以通过实现async-await轻松做到这一点。也许您没有看到它,但我将其包装到了一个异步函数中,但它仍然没有侦听并使其异步。我没有看到您使用
aync await
的任何地方。更新了我的回答谢谢@programoholic。我不确定我和你做的有什么不同,但我现在要等待。我可以把这个盒子装满谢谢。