gpt4 book ai didi

javascript - 如何在不添加到 Promise.prototype 的情况下为 Promise 创建自定义 .andThen() 链接函数?

转载 作者:行者123 更新时间:2023-12-04 08:52:36 27 4
gpt4 key购买 nike

我已经定义了一个自定义 Either类型并具有返回 Promise(Either(left,right)) 的函数.为了允许链接这些函数,我修改了 Promise 的原型(prototype),如下所示:

Promise.prototype.andThenE = function(andThen) {
return this.then(p => {
return p.fold(
e => Promise.reject(Either.left(e)),
s => andThen(s),
);
}).catch(c => c);
};
这使我可以编写如下代码:
const response = await functionXReturningPromiseEither(input).andThenE(functionYReturningPromiseEither).andThenE(...);
我知道扩展原生对象的原型(prototype)是不好的做法,我正试图取消这个 andThenE直接放在我的 Either并且无法使其正常工作/链接。
这是我对 Either 的简单实现:
const Either = {};

Either.fromPromise = promise => {
return promise.then(Either.right, Either.left);
};

Either.left = Either.failure = x => ({
map: f => Either.left(x), //no-op: no mapping if "left" value
fold: (l, r) => l(x), //apply "left" function to extract error value
andThen: f => Either.left(x), //or flatMap or chain or join: Left(Left(x)) -> Left(x)
dump: () => x, //for debugging
});

Either.right = Either.success = x => ({
map: f => Either.right(f(x)), //map only if "right"
fold: (l, r) => r(x), //apply "right" function to extract success value
andThen: f => f(x), //or flatMap or chain or join: Right(Right(x)) -> Right(x)
dump: () => x, //for debugging
});
如果我这样做,它将完美无缺:
const f = async (arr) => Either.right(arr.map(x => x+1));

const res = await Either.fromPromise(Promise.resolve([1])).andThenE(f).andThenE(f);
console.log(res.dump()); //[3] - is of type Either.right([3])
但是,我无法获得 andThenE成为 Either 的成员以任何有意义的方式。
我尝试这样做无济于事:
PromiseEither = promise => ({
andThenE: f => {
return PromiseEither(promise.then(p => {
console.log("inside promise");
return p.fold(
e => Promise.reject(Either.left(e)),
s => s.andThen(f),
);
}).catch(c => c));
},
});

Either.fromPromise = promise => {
PromiseEither(promise.then(Either.right, Either.left))
}
这不成功:
const res = await Either.fromPromise(Promise.resolve([1])).andThenE(f).andThenE(f);
console.log(res); //prints PromiseEither's structure and await is meaningless
我已经尝试了许多其他变体以了解其有效性。我认为这很简单,但经过数小时的撞击,我没有取得任何进展。我可能会错过什么?这甚至可能吗?
Link to fiddle

最佳答案

首先,我想强调我不会这样做。我不认为这是一个好主意,因为 Promise 已经有一个错误处理模型,这是我使用它时通常使用的。
如果你愿意,我会从头开始 - 并使用 .then作为您的类型(具有不同错误处理的延续)和 promise 之间的互操作点。
也就是说,做你想做的事情的标准方法是使用子类化(yuck)或 Symbol.species(甚至更糟糕)。我将展示第一个选项,并将第二个选项留给狂热的读者作为练习:

class PromiseEither extends Promise {
andThenE(f) {
return PromiseEither(this.then(p => {
console.log("inside promise");
return p.fold(
e => Promise.reject(Either.left(e)),
s => s.andThen(f),
);
}).catch(c => c)); // I would not do this .catch if I were you btw
}
});

}
我会警告不要使用 promise 子类化——这非常棘手。即使从一个新领域获得一份 Promise 副本并改变原型(prototype)(如 Node 中的 iframe 或 vm)也是更好的 IMO。

关于javascript - 如何在不添加到 Promise.prototype 的情况下为 Promise 创建自定义 .andThen() 链接函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64021563/

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