JavaScript中流动函数的最佳实践

JavaScript中流动函数的最佳实践,javascript,Javascript,我从请求中接收数据,在显示数据之前,我想对其进行处理,比如添加/格式化/生成/订购刚刚收到的原始内容 这里是我接收数据的方式,以及如何将数据发送到processData函数 this.httpService.get(`this/is/my/url`, body).then((data) => { this.processData(data).then((result) => { this.data = result; }, (error) =>

我从请求中接收数据,在显示数据之前,我想对其进行处理,比如添加/格式化/生成/订购刚刚收到的原始内容

这里是我接收数据的方式,以及如何将数据发送到
processData
函数

this.httpService.get(`this/is/my/url`, body).then((data) => {
    this.processData(data).then((result) => {
        this.data = result;
    }, (error) => {
        this.error = error;
    });
}, (error) => {
    this.error = error;
});
注意
processData
函数可能需要调用promises函数。
我看到了两种编写
processData
函数的方法:

第一条路

function processData(data) {
    return new Promise((resolve, reject) => {
        step1();

        function step1() {
            this.myService.yolo(data).then({
                //...
                step2();
            }, (error) => {
                reject(error);
            });
        }

        function step2() {
            this.myService.foo(data).then({
                //...
                step3();
            }, (error) => {
                reject(error);
            });
        }

        function step3() {
            this.myService.bar(data).then({
                //...
                step4();
            }, (error) => {
                reject(error);
            });
        }

        function step4() {
            //...
            resolve(data);
        }
   });
}
function processData(data) {
    step1().then((result) => {
        step2().then((result) => {
            step3().then((result) => {
                step4();
                return data;
            }, (error) => {
                reject(error);
            });
        }, (error) => {
            reject(error);
        });
    }, (error) => {
        reject(error);
    });

    function step1() {
        //...
    }

    function step2() {
        //...
    }

    function step3() {
        //...
    }

    function step4() {
        //...
    }
}
第二种方式

function processData(data) {
    return new Promise((resolve, reject) => {
        step1();

        function step1() {
            this.myService.yolo(data).then({
                //...
                step2();
            }, (error) => {
                reject(error);
            });
        }

        function step2() {
            this.myService.foo(data).then({
                //...
                step3();
            }, (error) => {
                reject(error);
            });
        }

        function step3() {
            this.myService.bar(data).then({
                //...
                step4();
            }, (error) => {
                reject(error);
            });
        }

        function step4() {
            //...
            resolve(data);
        }
   });
}
function processData(data) {
    step1().then((result) => {
        step2().then((result) => {
            step3().then((result) => {
                step4();
                return data;
            }, (error) => {
                reject(error);
            });
        }, (error) => {
            reject(error);
        });
    }, (error) => {
        reject(error);
    });

    function step1() {
        //...
    }

    function step2() {
        //...
    }

    function step3() {
        //...
    }

    function step4() {
        //...
    }
}
第二种方法让我觉得更符合逻辑,因为你不需要看到
步骤
函数的内容就可以理解发生了什么,但我发现这个符号太混乱了
有10个步骤,这是不可读的


所以我想知道做这件事的好方法是什么

您如何使用承诺的关键之处在于,您没有从
然后
回调中返回任何内容,这就是您如何以一种有用的方式将承诺链接在一起

您的
processData
可以如下所示:

function processData(data) {
    step1().then(step2).then(step3).then(step4);

    function step1() {
        //...
    }

    // ...
}
function step1() {
    return this.myService.yolo(data).then(result => {
        return transformedResult;
    });
}
…步骤如下所示:

function processData(data) {
    step1().then(step2).then(step3).then(step4);

    function step1() {
        //...
    }

    // ...
}
function step1() {
    return this.myService.yolo(data).then(result => {
        return transformedResult;
    });
}
…这当然意味着,除非它们很复杂,否则不需要将它们分解为各自的功能:

function processData(data) {
    return this.myService.yolo(data)
        .then(result => {
            return /*...`result` transformed in some way...*/;
        })
        .then(result => anotherAsyncCall(result))
        .then(result => {
            return /*...`result` transformed again... */;
        })
        .then(result => anotherAsyncCall(result)) // If no transformation needed when passing it on
        .then(/*etc.*/);
}

这是因为每次调用
都会返回一个承诺。承诺要么用您从
然后
回调返回的值进行解析,要么如果您返回了承诺,则根据该承诺的解析/拒绝来解析/拒绝该承诺。

谢谢您的回答!如何处理承诺错误?就像第2步失败一样,转到第4步?@Citizen:拒绝会一直传播,直到它们到达为拒绝注册的第一个处理程序,跳过仅为解决而注册的任何处理程序。因此
a.然后(b).然后(c).catch(…)
将(有效地)直接从
a
转到
catch
,如果
a
拒绝而不是解析。