gpt4 book ai didi

用于处理多个未知回调的 JavaScript 函数

转载 作者:太空宇宙 更新时间:2023-11-04 15:37:05 25 4
gpt4 key购买 nike

我有一个场景,我想将 2 个或更多函数(作为参数)发送到处理函数中,并让该处理函数执行每个传递的函数作为前面函数的回调函数。

这是我要编写的函数的一般概念:

function functionChain() {
// MAKE SURE WE HAVE AT LEAST 1 PARAMETER
if ( arguments.length < 1 ) { return; }

// for each parameter, call it (as a function)
for ( var i=0; i<arguments.length; i++) {
if ( typeof arguments[i] === 'function' ) {
call arguments[i];
}
}
}
// example
functionChain( function1, function2, function3 );

...所以在上面的代码中,每个函数都会被连续调用。

我遇到的问题是如何在前一个函数完成时将每个调用视为回调。

我处理这个问题的方法是有一个变量(为了简单起见,我们只说一个名为 functionChainComplete 的全局变量),然后等待启动下一个函数 - 当然,我调用的每个函数都会将 functionChainComplete 设置为 true 。所以,像这样:

// set global var for tracking
var functionChainComplete;

function functionChain() {
// MAKE SURE WE HAVE AT LEAST 1 PARAMETER
if ( arguments.length < 1 ) { return; }

// SET GLOBAL VAR TO FALSE
functionChainComplete = true;

// for each parameter, call it (as a function)
for ( var i=0; i<arguments.length; i++) {
if ( typeof arguments[i] === 'function' ) {
if ( functionChainComplete == true ) {
// call the next function and wait for true again
functionChainComplete = false;
call arguments[i];
} else {
// try again in 50 ms (maybe setTimeout)?
}
}
}
}

function1() {
// do something, and when done, reset functionChainComplete
functionChainComplete = true;
}

function2() {
// do something, and when done, reset functionChainComplete
functionChainComplete = true;
}

function3() {
// do something, and when done, reset functionChainComplete
functionChainComplete = true;
}

// example
functionChain( function1, function2, function3 );

正如您所看到的,上面的代码没有解决回调部分,并且我不确定从这里到哪里获取它 - 我怀疑某种递归函数?我被困住了。

最佳答案

假设您有一个函数 double,它接受一个参数 x 和一个回调 k

const double = (x, k) =>
k(x * 2)

double(2, console.log) // 4
double(3, console.log) // 6

现在假设我们要连续运行 3 次

const double = (x, k) =>
k(x * 2)

const tripleDouble = (x, k) =>
double(x, y =>
double(y, z =>
double(z, k)))

tripleDouble(2, console.log) // 16
tripleDouble(3, console.log) // 24

但是,我们当然必须对每个延续进行静态编码(y => ...z => ...)。我们如何使用可变数量(数组)函数来完成这项工作?

const double = (x, k) =>
k(x * 2)

const composek = (...fs) => (x, k) =>
fs.reduce((acc, f) =>
k => acc(x => f(x, k)), k => k(x)) (k)

const foo = composek(double, double, double)

foo(2, console.log) // 16
foo(3, console.log) // 24

这对于一些抽象来说已经成熟了,并且介绍了我最喜欢的 monad,Continuation Monad。

const Cont = f => ({
runCont: f,
chain: g =>
Cont(k => f(x => g(x).runCont(k)))
})

Cont.of = x => Cont(k => k(x))

const composek = (...fs) => (x, k) =>
fs.reduce((acc,f) =>
acc.chain(x =>
Cont(k => f(x,k))), Cont.of(x)).runCont(k)

const double = (x, k) =>
k(x * 2)

const foo = composek(double, double, double)

foo(2, console.log) // 16
foo(3, console.log) // 24

如果您可以自由地更改要链接的函数,这会清理更多一些 - 在这里,double 有 1 个参数并返回一个 Cont 而不是将回调作为第二个参数

const Cont = f => ({
runCont: f,
chain: g =>
Cont(k => f(x => g(x).runCont(k)))
})

Cont.of = x => Cont(k => k(x))

// simplified
const composek = (...fs) => (x, k) =>
fs.reduce((acc,f) => acc.chain(f), Cont.of(x)).runCont(k)

// simplified
const double = x =>
Cont.of(x * 2)

const foo = composek(double, double, double)

foo(2, console.log) // 16
foo(3, console.log) // 24

当然,如果double实际上是异步的,它的工作原理是一样的

// change double to be async; output stays the same
const double = x =>
Cont(k => setTimeout(k, 1000, x * 2))

const foo = composek(double, double, double)

foo(2, console.log) // 16
foo(3, console.log) // 24

关于用于处理多个未知回调的 JavaScript 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44250521/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com