Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/473.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/.htaccess/6.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
Javascript 从Angular 4中先前http响应的成功调用http请求(避免回调地狱)_Javascript_Angular_Callback - Fatal编程技术网

Javascript 从Angular 4中先前http响应的成功调用http请求(避免回调地狱)

Javascript 从Angular 4中先前http响应的成功调用http请求(避免回调地狱),javascript,angular,callback,Javascript,Angular,Callback,我正在使用一个应用程序,在这个应用程序中,我需要调用HTTP响应以确保HTTP调用成功。我应该如何重构代码以避免回调地狱 我目前的代码是: Component.ts SomeFunction() { const param2 = {ind_1: value_1, ind_2: value_2}; this.service.callFunction1(param) .subscribe( f1_res => { if (f

我正在使用一个应用程序,在这个应用程序中,我需要调用HTTP响应以确保HTTP调用成功。我应该如何重构代码以避免回调地狱

我目前的代码是:

Component.ts
SomeFunction() {
    const param2 = {ind_1: value_1, ind_2: value_2};
    this.service.callFunction1(param)
        .subscribe(
        f1_res => {
           if (f1_res.status === 'success' ) {
               this.service.callFunction2(f1_res)
                    .subscribe(
                        f2_res => {
                            this.service.callFunction3(f2_res)
                                .subscribe(
                                     f3_res => console.log('done', f3_res),
                                     f3_err => console.log(err)
                                 );
                        },
                        f2_err => console.log(f2_err)
                    )
           }
        },
        f1_err => console.log(err)
    );

}
我的发球是非常标准的角度发球

Service.ts
callFunction1(param) {
     return this.http.post<any>( 'someurl.com', param );
}

callFunction2(param) {
     return this.http.post<any>( 'someurl.com', param );
}

callFunction3(param) {
     return this.http.post<any>( 'someurl.com', param );
}
Service.ts
调用函数1(参数){
返回this.http.post('someurl.com',param);
}
调用函数2(参数){
返回this.http.post('someurl.com',param);
}
调用函数3(参数){
返回this.http.post('someurl.com',param);
}

我知道这很糟糕,但如何重构它?

这是一个简单的
mergeMap
链的例子。大概是这样的:

this.service.callFunction1(params).pipe(
  mergeMap(res => this.service.callFunction2(res)),
  mergeMap(res => this.service.callFunction3(res)),
)
  .subscribe(
    (result) => console.log('done', result),
    (error) => console.log('error in chain', error),
  );
SomeFunction() {
const param2 = {ind_1: value_1, ind_2: value_2};
this.service.callFunction1(param)
  .flatMap(f1_res => f1_res.status === 'success' ? this.service.callFunction2(f1_res) : Observable.throw("f1 error"))
  .flatMap(f2_res => this.service.callFunction3(f2_res))
  .subscribe(
    f3_res => console.log('done', f3_res),
    error => console.error(error)
    );
}
这是一张工作票

编辑:当然,您可以将那些
response.status==='success'
检查打包到函数中,或者直接打包到函数中,但是如果您只是检查HTTP错误,它们都会在底部的错误处理程序中断开链

function doStuff(param) {
    this.service.callFunction1(param)
        .subscribe().then(step1(param)
            .flatMap((step1Result) => step2(step1Result)
                .flatMap((step2Result) => step3(step2Result))
                .map((step3Result) => {
                    let doStuffResult = step3Result;
                    if (doStuffResult !== null) {
                        return doStuffResult;
                    }
                })));
}

function step1(f1_res) {
    let result: any = null;
    this.service.callFunction1(f1_res)
        .subscribe(res => {
            if (res.status === 'success') {
                // ...
                this.result = res;
            }
        }, error => {
            console.log(error);
        });

    return Rx.Observable.of(result);
}

function step2(f2_res) {
    let result = null;
    this.service.callFunction2(f2_res)
        .subscribe(
            f2_res => {
                if (f2_res.status === 'success') {
                    this.result = f2_res;
                }
            }, error => { console.log(error) });
    // ...
    return Rx.Observable.of(result);
}

function step3(f3_res) {
    let result = null;
    this.service.callFunction2(f3_res)
        .subscribe(
            f3_res => {
                this.result = f3_res;
            }, error => { console.log(error) });
    // ...
    return Rx.Observable.of(result);
}

一种非常优雅的方法是,将每个订阅的呼叫作为自己的单个责任单元,并创建一个新的
可观察的
,这样每个单元的行为仍然是独立的,但它们在一个链中被触发。

您可以通过使用(您仍然有回调…)稍微减少代码

e、 g.您的代码可以转换为如下内容:

this.service.callFunction1(params).pipe(
  mergeMap(res => this.service.callFunction2(res)),
  mergeMap(res => this.service.callFunction3(res)),
)
  .subscribe(
    (result) => console.log('done', result),
    (error) => console.log('error in chain', error),
  );
SomeFunction() {
const param2 = {ind_1: value_1, ind_2: value_2};
this.service.callFunction1(param)
  .flatMap(f1_res => f1_res.status === 'success' ? this.service.callFunction2(f1_res) : Observable.throw("f1 error"))
  .flatMap(f2_res => this.service.callFunction3(f2_res))
  .subscribe(
    f3_res => console.log('done', f3_res),
    error => console.error(error)
    );
}

您的函数步骤[123]将返回Observable,并将触发并忘记servicefunction调用的结果。