Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/475.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 具有promise控制流的函数式编程语法_Javascript_Functional Programming - Fatal编程技术网

Javascript 具有promise控制流的函数式编程语法

Javascript 具有promise控制流的函数式编程语法,javascript,functional-programming,Javascript,Functional Programming,虽然更多地适应javascript中的函数编程,但我想知道如何最好地解决以下问题(关于函数实践和简单易读的代码) 我有一个函数,它返回一个对象的替代版本 函数完成此操作(obj){ 返回{ …obj, “改变了” } } 很好!一个做一件事的简单函数,可以在各种情况下使用,也可以与其他函数组合使用 对于一个对象 //Ex 1-一个函数 让改变=做这件事(原件); //Ex 2-许多函数 let change=andMore(doThat(doThis(original)); //Ex 3-许多

虽然更多地适应javascript中的函数编程,但我想知道如何最好地解决以下问题(关于函数实践和简单易读的代码)

我有一个函数,它返回一个对象的替代版本

函数完成此操作(obj){
返回{
…obj,
“改变了”
}
}
很好!一个做一件事的简单函数,可以在各种情况下使用,也可以与其他函数组合使用

对于一个对象
//Ex 1-一个函数
让改变=做这件事(原件);
//Ex 2-许多函数
let change=andMore(doThat(doThis(original));
//Ex 3-许多需要附加参数的函数
let changed=andMore(doThat(doThis(原文为“foo”)、“bar”)、“foo”);
//或
让改变=更多(
多塞(
doThis(原文为“foo”),
“酒吧”
),
“福”
);
对于对象数组
//Ex 4-一个函数
let changed=原件.map(doThis);
//Ex 5-许多功能
换成原样
.map(doThis)
.map(doThat)
.地图(及更多);
//例6
换成原样
.map(original=>doThis(original,'foo'))
.map(已更改=>doThat(已更改,'bar'))
.map(更改=>andMore(更改为'foo'));
但是,函数(出于某种原因)必须异步执行它的操作,因此它们返回一个
承诺
,并用预期值解析,而不是像以前那样返回

对于一个对象
//Ex 7-一个函数
doThis(原件)
。然后(更改=>{
//继续
});
//Ex 8-许多函数
doThis(原件)
.那么(就这样)
.然后(还有更多)
。然后(更改=>{
//继续
});
//Ex 9-许多需要附加参数的函数
doThis(原文为“foo”)
.then(changed=>doThat(changed,'bar'))
.然后(更改=>andMore(更改为'foo'))
。然后(更改=>{
//继续
});
对于对象数组
//Ex 10-一个函数
Promise.all(originals=>originals.map(original=>doThis(original)))
。然后(更改=>{
//继续
});
//Ex 11-许多功能
Promise.all(originals.map(original=>doThis(original)))
.then(changed=>Promise.all(changed.map(oneChanged=>doThat(oneChanged)))
.then(changed=>Promise.all(changed.map(oneChanged=>andMore(oneChanged)))
。然后(更改=>{
//继续
});
//Ex 12-许多需要附加参数的函数
Promise.all(originals.map(original=>doThis(original,'foo'))
.then(changed=>Promise.all(changed.map(oneChanged=>doThat(oneChanged,'bar')))
.then(changed=>Promise.all(changed.map(oneChanged=>andMore(oneChanged,'foo'))
。然后(更改=>{
//继续
});
即使有这样一个运行一个或三个类似函数的简化案例,一些示例的语法也开始变得非常难看

我想造成这种情况的两个主要原因是

  • 当需要额外的参数时
  • 对于返回承诺的对象数组,需要包装成
    Promise.all
  • “问题1”的一个解决方案是让函数返回一个函数,在使用主函数的任何地方都不需要包装函数。例如:

    函数完成此操作(选项){
    返回函数(obj){
    // ...
    };
    }
    //Ex 6现在可以简化为
    某物链
    .map(doThis('foo'))
    .map(点('bar'))
    .map(andMore('foo'))
    
    但这是好的函数式编程吗?还是有更好的方法来解决这个问题

    “问题2”的一个解决方案是将函数包装在可重用函数中,该函数检查传递的参数是对象还是数组,对于后者,为数组中的每个对象运行回调:

    函数oneOrMany(回调){
    return(subject)=>Array.isArray(subject)?
    map(oneSubject=>callback(oneSubject))
    :
    回调(主题);
    }
    const doThis=oneOrMany(原件=>{
    返回{
    起初的
    “改变了”
    };
    });
    
    现在,doThis可以用于单个对象(如Ex 8)和对象数组(而不是Ex 11):

    //Ex
    doThis(原件)
    .那么(就这样)
    .然后(还有更多)
    。然后(更改=>{
    //继续
    });
    
    看起来比Ex 11简单得多,可读性也更高。但这是一个好的函数式编程吗?还是有更好的方法来解决这个问题

    附加参数的一个解决方案是使函数 返回一个函数,以消除对包装器函数的需要 无论在何处使用主功能。
    但这是好的函数式编程吗?还是有更好的方法 解决这个问题

    这很好。它被称为

    您也可以通过编程来完成,而不是重写所有多参数函数,或者在调用处显式地执行部分应用程序,但这主要是语法上的差异

    一种解决方案,用于
    承诺。所有
    -包装返回的对象数组
    承诺可以是将函数包装在一个可重用的函数中
    检查传递的参数是对象还是数组,以及
    然后,对数组中的每个对象运行回调
    无论是对于单个对象还是对象数组,这看起来都非常有用
    更简单易读。
    但这是好的函数式编程吗

    不,一点也不。FP是关于特定于类型,而不是编写根据传递的内容执行不同操作的开放函数。而是显式执行:

    function manyParallel(callback) {
        return function(subject) {
            return Promise.all(subject.map(callback));
        };
    }
    
    manyParallel(doThis)(originals)
    .then(manyParallel(doThat))
    .then(manyParallel(andMore))
    .then(manyParallel(changed => {
        // continue
    }));
    // or alternatively (but different):
    manyParallel(original => original
        .then(doThis)
        .then(doThat)
        .then(andMore)
    )(originals)
    .then(manyParallel(changed => … ));