javascript - 如何使用异步等待和对反应流的突变对命令式代码进行建模
问题描述
let drawer = {};
let stacks = {};
async function actionDealCard(hidden) {
let previousMutation = drawer.mutation;
drawer.mutation = true;
await new Promise(resolve => {
setTimeout(resolve, previousMutation?500:100);
console.log('animation happening');
});
stacks.mutation = hidden;
}
async function mainFunction() {
let deals = [1,2,3];
for (let key in deals) {
await actionDealCard(key);
}
console.log(stacks, drawer);
}
mainFunction();
以上是我的代码的简化版本。我使用命令式编码风格实现了这一点。现在我想把它变成反应流。我怎么做?
我试过这样的事情:
// I need an event stream that describes when to mutate drawer
// to pass to DrawerProperty function
// This might be a bus to simplify the solution but buses are bad.
let esDrawerMutate = ???
let drawer = DrawerProperty(esDrawerMutate);
async function actionDealCard(key) {
// I have no clue what's going on here
}
let deals = Bacon.fromArray([1,2,3]);
let esMain = deals.flatMap(key => {
return Bacon.fromPromise(actionDealCard(key));
});
esMain.log();
function DrawerProperty(esMutate) {
return Bacon.update({},
[esMutate, _ => _.mutation = true]);
}
function StacksProperty(esMutate) {
return Bacon.update({},
[esMutate, _ => _.mutation = true]);
}
当我上面的代码运行时,这是输出:
animation happening
animation happening
animation happening
{
"mutation": "2"
} {
"mutation": true
}
我想我的目标是以功能样式产生相同的输出。
解决方案
我主要取消了您对此的评论,如果有任何需要澄清的地方,请告诉我。我正在使用我的图书馆中的一些方法。pipe
只是将函数链接在一起,如果它们是异步的,则等待它们,tap
将调用您传递的函数并忽略输出,返回输入
const drawer = { cards: [1, 2, 3], did_mutate: false }
const popCardFromDrawer = () => drawer.cards.pop()
const animate = () => {
console.log('animation happening')
const animationTime = drawer.did_mutate ? 100 : 500
drawer.did_mutate = true
return new Promise(resolve => setTimeout(resolve, animationTime))
}
const stacks = { cards: [] }
const addCardToStacks = card => { stacks.cards.push(card); return stacks }
const { pipe, tap } = rubico
const dealAction = pipe([
popCardFromDrawer, // () => card
tap(animate), // card => card
addCardToStacks, // card => stacks
])
const main = async () => {
while (drawer.cards.length > 0) {
await dealAction()
console.log('drawer', drawer, 'stacks', stacks)
}
}
main()
<script src="https://unpkg.com/rubico/index.js"></script>
推荐阅读
- javascript - 如何将有效负载数组更改为 Node Red 中的有效负载对象?
- ruby-on-rails - 需要为每个新版本或应用程序安装 rails 吗?
- c++ - 使用“多个”命名空间单行
- react-native - React Native Expo Video av-expo -- 直接全屏播放
- git - 有没有办法检查远程 git repo 是否有更改,而无需实际获取更改?
- asp.net-mvc - Application Insights - 应用程序映射缺少传入请求节点
- powershell - 在外部窗口中操作 Afx OLE 控件
- sql - 如何使 MSSQL 忽略用户正在给予的价值中的“'”?
- javascript - argMax 将数组作为轴做什么?
- excel - 无法在 vba 中激活变量分配表