思源有声书制作可行性

本贴最后更新于 198 天前,其中的信息可能已经天翻地覆

经过一段时间摸索,我发现思源比其他笔记软件都更适合我的编辑需求。

因为在学语言,在将教材转换成文档的过程中,对有声的需求颇高(而纯播放器中的音频字幕又不方便添加说明阐释),所以想知道在本身已有字幕文件的情况下,有没有快速制作有声文档的可能?

通过观察其他 quicker 动作,我学会了通过直接在每个块后添加 {: attrName=""} 批量设置属性。所以,我自己的思路:可以通过这种方式快速将字幕文档中的每句/段话绑定 "start" "end" "audiofileName" 属性,然后粘贴进入思源,再在所有这些句子前后加入教材其他解释说明,也许就可以达到有声文档的制作。

但是我不太懂编程,缺失了最关键一步:如何通过代码片段获取这些属性,并控制播放(双击块,或者通过代码在块前或块后添加某个 emoji 图标,点击图标播放块对应的属性中的 audiofileName 文件 播放 start 到 end 时间的内容)。

目前有搜索到一些插件可以通过自定义音频块时间属性,跳转对应位置,所以感觉我的需求在思源中也许也是有可能做到的,不过我的需求要多几点:

  • 希望能直接点击播放,而不只是跳转后再点击播放
  • 可以在 end 对应时间结束播放

有没有了解思源和 js 的大佬们能不吝赐教 🙏

  • 思源笔记

    思源笔记是一款隐私优先的个人知识管理系统,支持完全离线使用,同时也支持端到端加密同步。

    融合块、大纲和双向链接,重构你的思维。

    25910 引用 • 107384 回帖 • 1 关注
  • Q&A

    提问之前请先看《提问的智慧》,好的问题比好的答案更有价值。

    9948 引用 • 45190 回帖 • 77 关注

相关帖子

被采纳的回答
  • wilsons 3 1 赞同

    我说的添加 audio 标签不一定非要在 HTML 中显式的添加,用 js 隐式添加即可,但本质还是添加了 audio 标签。

    根据你的需求我实现了这个功能,不知道是否符合你的预期,仅供参考。

    首先,用 vscode 插件的 Markdown 源码中添加以下代码(思源中直接粘贴也可以,但 vscode 插件最保险,思源直接粘贴可能自定义属性被过滤,如果没过滤就可以,自己试试,我这边二者都可以)。

    demo1 ▶️ {: id="20241126195837-wtsvkrg" custom-attrname="" custom-audiofilename="file:///yourpath.mp3" custom-end="40" custom-start="30"} demo2 ▶️ {: id="20241126195837-wtsvkrg" custom-attrname="" custom-audiofilename="file:///yourpath.mp3" custom-end="30" custom-start="20"}

    然后,思源 js 代码片段中添加以下代码

    https://gitee.com/wish163/mysoft/blob/main/%E6%80%9D%E6%BA%90/%E6%80%9D%E6%BA%90%E9%80%9A%E8%BF%87%E8%87%AA%E5%AE%9A%E4%B9%89%E5%B1%9E%E6%80%A7%E6%92%AD%E6%94%BE%E5%9D%97%E9%9F%B3%E9%A2%91.js

    const attrName = 'attrname';
    const audioFileAttrName = 'audiofilename';
    const startTimeAttrName = 'start';
    const endTimeAttrName = 'end';
    const playEmoji = '▶️';

    这个几个参数根据自己需要修改,要与 Markdown 中的保持一致。

    注意:js 代码里不需要带 custom-前缀,但 Markdown 代码里必须加 custom-前缀,注意属性使用小写,否则思源也会转换为小写。

    祝你好运 🍀

    效果:

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...
  • 怎么快速插入音频,并设置锚文本点击即播放? 可参考这个帖子,有了 audio 标签后,想怎么做,怎么做,比你说的方式简单一些

    1 回复
  • towfd via Linux

    这个帖子就是我之前发的,正是因为这个帖子的思路在我实际操作过程中发现很麻烦(需要切割句子音频,而且资源文件夹会积累非常多琐碎的文件),而且有时我需要播放整段,有时需要播放单句,这个也不好操作。所以我才换了种思路,这样就不会有那么多文件,而且可以直接给整段设置独立的时间,如果代码产出来了,其实整个工作流要简单很多。

    1 回复
  • 一样的

    只要设置 audio.currentTime = startTime; 就是开始时间

    播放到某时间点结束,可以这样

    // 监听时间更新事件,检查是否到达结束时间 audio.addEventListener('timeupdate', function() { if (audio.currentTime >= endTime) { audio.pause(); // 停止播放 } });

    然后调用播放的地方可以 playAudio(event, mp3, startTime, endTime)

    总之,写代码也是这个思路,要播放音频就得自己加个 audio 标签。至于触发方式我觉得可以在文字块前或后加个标志图标,比如声音图标,然后给这个图标添加事件触发播放。获取块属性可以用 api /api/attr/getBlockAttrs,但从你的需求来看,直接通过 dom 属性查找元素更符合需求,比如,document.querySelector('[custom-attrname="xxxx"]')。

    1 回复
  • towfd 3 评论 via Linux

    一定要在文本里加 audio 标签吗?js 没法直接获取文件名播放吗?主要转变成 html 后编辑比较麻烦

    1 回复
    以我个人写 HTML 和 js 的经验来看还是用 audio 居多,就算不显示出来也是播放隐藏的 audio。不过确实没做过在思源里播放音频,可能有别的方法
    EmptyLight
    @EmptyLight 我主要不想把文本设置成 html 块,那直接每个文档插入音频(思源插入的音频本身就带 audio 标签),但是一个文档可能有多个音频,点击图标时播放定位块属性中的 audiofile 和对应时间可行吗?
    towfd
    @towfd 这个我确实没有尝试过,需要等其他人知道的来回答了
    EmptyLight
  • wilsons 3 1 赞同

    我说的添加 audio 标签不一定非要在 HTML 中显式的添加,用 js 隐式添加即可,但本质还是添加了 audio 标签。

    根据你的需求我实现了这个功能,不知道是否符合你的预期,仅供参考。

    首先,用 vscode 插件的 Markdown 源码中添加以下代码(思源中直接粘贴也可以,但 vscode 插件最保险,思源直接粘贴可能自定义属性被过滤,如果没过滤就可以,自己试试,我这边二者都可以)。

    demo1 ▶️ {: id="20241126195837-wtsvkrg" custom-attrname="" custom-audiofilename="file:///yourpath.mp3" custom-end="40" custom-start="30"} demo2 ▶️ {: id="20241126195837-wtsvkrg" custom-attrname="" custom-audiofilename="file:///yourpath.mp3" custom-end="30" custom-start="20"}

    然后,思源 js 代码片段中添加以下代码

    https://gitee.com/wish163/mysoft/blob/main/%E6%80%9D%E6%BA%90/%E6%80%9D%E6%BA%90%E9%80%9A%E8%BF%87%E8%87%AA%E5%AE%9A%E4%B9%89%E5%B1%9E%E6%80%A7%E6%92%AD%E6%94%BE%E5%9D%97%E9%9F%B3%E9%A2%91.js

    const attrName = 'attrname';
    const audioFileAttrName = 'audiofilename';
    const startTimeAttrName = 'start';
    const endTimeAttrName = 'end';
    const playEmoji = '▶️';

    这个几个参数根据自己需要修改,要与 Markdown 中的保持一致。

    注意:js 代码里不需要带 custom-前缀,但 Markdown 代码里必须加 custom-前缀,注意属性使用小写,否则思源也会转换为小写。

    祝你好运 🍀

    效果:

    2 回复
  • towfd via Linux

    解答迅速,并且直接手把手喂饭,你就是互联网大善人! 思源有你是它的福气!🙇🙇🙇

    按照你给的代码,增加了一步字幕时间格式转换,可以完全正常地播放对应时段音频。

    唯一还有一点疑惑是,我不懂为什么要多自定义一个空的 attrname 属性,本来想删掉,开始只删了前面两处,但发现删了就没法正常使用了,搜索发现后面还有个回调函数也在用它,我看不懂这个空属性是用来干嘛的。

    1 回复
  • wilsons 2

    谢谢!微薄之力,不敢当此殊荣哈。

    不懂为什么要多自定义一个空的 attrname 属性

    这个根据你之前的设定写的,这个作用是识别自定义块的标志,如果去掉,就无法识别到这个块是你自定义的了。

    不过,这个属性并不是必须的,如果想删除的话,可以把 observeAudioBlock 调用那里的 attrName 变量换成 audioFileAttrName 变量即可,这样就可以用音频文件属性查找自定义块了,如图所示

    image.png


    另外,早上我已经把代码更新到 0.0.2,这个版本增加了按钮鼠标悬停效果,增加了对自定义 emoji 的支持。

    自定义 Emoji 的使用方法:

    首先,Markdown 中添加如下代码,这里主要不同是:path/demo:这里,这是自定义 Emoji 的写法。

    demo3 :path/demo: {: id="20241127091438-k3nryro" custom-end="30" custom-start="20" custom-attrname="" custom-audiofilename="file://yourpath/xxxx.mp3"}

    然后在 js 中,playEmojiCustom 参数设置为 path/demo 即可。

    注意,自定义 Emoji 无需舔加图片扩展名。

    假设自定义表情路径是,data/emojis/demo/demo.png,则只需要填写:demo/demo 即可。

    自定义 Emoji 可以和普通 Emoji 共存,不使用该参数,填空即可。

    代码(同之前的是同一个网址):

    https://gitee.com/wish163/mysoft/blob/main/%E6%80%9D%E6%BA%90/%E6%80%9D%E6%BA%90%E9%80%9A%E8%BF%87%E8%87%AA%E5%AE%9A%E4%B9%89%E5%B1%9E%E6%80%A7%E6%92%AD%E6%94%BE%E5%9D%97%E9%9F%B3%E9%A2%91.js

    1 回复
  • towfd via Linux

    真的非常感谢你 🙏 我在有声书的诉求上已经折腾了太久。epub 本身支持有声书,但是编辑太麻烦,完工后再修改也麻烦,做笔记也麻烦,支持的有声阅读软件也难找。纯播放器字幕显示也不适合阅读,你真的解决了我的大麻烦,帮助了我太多,真的太感谢你了!

    我选择思源不仅因为它本身(超级块非常方便排版,闪卡不会破坏原文档,不用导出 anki,且非常适合记忆有前后文的信息),还因为它的有解决个性化诉求的可能性和社区。虽然我自己技术小白,实现困难,但却总有人回复(而且两次回复我的都是你!)我觉得像你们本身懂技术、有自我解决问题的能力的人,每天却如此高强度刷社区,回复需要帮助的人,先不说技术付出,单单是愿意为陌生人付出宝贵的时间这本身就已经是可贵的善举了!思源有你们真的了不起!

    1 回复
  • wilsons 2

    也谢谢你!你是一个懂得感恩的人,别的不说,光这一点所有努力都值得了!

    刚才好像在哪看到你说平板有问题来着,找不到了,我刚才在手机试了下,最新版手机上没问题,但移动端是没有鼠标悬停效果的。

    另外,要注意,确保资源文件放到了 assets 目录里或者是在线版的,如果音频文件是本地文件,在移动端是无法访问的。


    题外话,早上回复了一个问题, 希望思源笔记中能够点击单词进行播放单词的声音 - wilsons 的回帖 我现在突然觉得,这种方案或许是更方便的方案。

    你可以正常输入文本,只需要在需要播放音频的地方插入一个链接就可以了,然后后面我再改进下,比如可以设置 URL 参数 start=xx&end=xxx 等,然后就能达到你现在同样的效果了。

    如果批量插入,也可以 [文本](path/xxx.mp3?start=xx&end=xxx) 来插入链接就可以了,链接文本同样可以是 Emoji。

    目前仅仅是觉得可行,后续空了试试看,如果可行的话可以把这个链接方案完善下。

    1 回复
  • towfd 1 赞同 via Linux

    是我修改属性名的问题,在各种复制粘贴中有的改了有的没改比较混乱,电脑可能因为缓存问题,能正常播放,导致我以为是移动端有啥问题。但是我自己发现问题改过来后已经能正常使用了,所以我随机又把回复删了。

    我昨晚也看了那个贴(因为和我的需求比较像),我上个贴也是说这种 [文本](path/xxx.mp3?start=xx&end=xxx) 格式插入后,点击不能直接播放,而是会直接跳转到资源页再点击才能播放,而直接按思源本身的方式插入音频,播放控件太大了,会影响页面布局排版。不过现在版本已经完全满足我目前的需求了,至于 srt 字幕文本到链接还是属性的批量格式替换,怎么转都差不多,不过链接的形式可能更好适配其他 md 笔记软件。

  • towfd via Linux

    大佬,有点不好意思,又跑来麻烦你,我想问问,就是如果想让每级标题前面(或后面)出现一个按钮,点击可以连续播放它下面的所有有声句,代码可以怎么修改?

    1 回复
    1 操作
    towfd 在 2024-11-29 17:20:39 更新了该回帖
  • wilsons 1

    你这个按钮怎么加的? 具体什么按钮?有什么特征?

    1 回复
  • towfd via Linux

    就是和原来类似的加一个播放按钮,只是这个按钮是连续播放该级标题下的所有有声句(句子本身通常是连贯的,所以应该只需要读取第一个句子的 start 和最后一个句子的 end ,可能判定标题正文是在哪里结束的更麻烦点?因)。按钮具体什么样倒没有设定,也是 emoji 图标,和单句的图标有区别就行,你先随便设定一个图标就行。

    1 回复
  • wilsons 1

    已按照你说的方式实现 https://gitee.com/wish163/mysoft/blob/main/%E6%80%9D%E6%BA%90/%E6%80%9D%E6%BA%90%E9%80%9A%E8%BF%87%E8%87%AA%E5%AE%9A%E4%B9%89%E5%B1%9E%E6%80%A7%E6%92%AD%E6%94%BE%E5%9D%97%E9%9F%B3%E9%A2%91.js

    然后,修改下下面这个参数即可。

    // 标题播放按钮 Emoji,不使用该参数,填空即可
    //(该功能是通过获取标题下的所有音频的最小开始时间和最大结束时间实现的,因此不通用,如果你的音频不是连续播放的,勿用此功能)
    const playEmojiHead = ''; //⏩

    1 回复
  • towfd

    谢谢谢谢,太麻烦你了 🙇‍♀️🙇‍♀️🙇‍♀️

    由于字幕本身时间格式是这样式的 00:00:10,500,之前版本我就让 ai 增加了一步

    // 将SRT时间格式(例如 "00:00:10,500")转换为秒数 function convertSrtTimeToSeconds(timeStr) { const [time, millis] = timeStr.split(','); const [hours, minutes, seconds] = time.split(':').map(Number); return hours * 3600 + minutes * 60 + seconds + millis / 1000; }
    observeAudioElements('custom-' + attrName.replace(/^custom\-/i,''), block => { // ...... audioPlayBtn?.addEventListener('click', (event) => { const file = block.getAttribute('custom-' + audioFileAttrName.replace(/^custom\-/i,'')); let startTime = block.getAttribute('custom-' + startTimeAttrName.replace(/^custom\-/i,'')); let endTime = block.getAttribute('custom-' + endTimeAttrName.replace(/^custom\-/i,'')); // 将SRT时间格式转换为秒数 startTime = convertSrtTimeToSeconds(startTime); endTime = convertSrtTimeToSeconds(endTime);

    但新增加的代码,我再让 ai 修改,它只修改了 onHeadPlayEmojiAddition(head) 中的两处 starts.push(convertSrtTimeToSeconds(start));starts.push(convertSrtTimeToSeconds(start));,但尝试点击却并没有播放成功,感觉似乎并没有修改完全,但代码里面已经出现了太多 start 和 end,我的脑子也是一团浆糊,也不知道哪些该修改哪些不该。

    另外,这个标题按钮似乎只能支持原生 emoji,我自己保存的图标无论是以文件名的形式'playall',还是以在思源中直接复制图标后生成的格式 ':playall:' 似乎都不起作用。因为我测试过程中,原生 emoji 虽然可能因为前面修改的不完善导致不能播放,但是会出现悬浮手指,而自定义的 emoji 则不会出现。不过这点不修改也不会影响啥,无论什么形式的 emoji 只要能正常播放就行。已经太麻烦你了。

    1 回复
  • wilsons 1 1 赞同

    0.0.4 兼容时间格式,标题 Emoji 兼容自定义 Emoji

    https://gitee.com/wish163/mysoft/blob/main/%E6%80%9D%E6%BA%90/%E6%80%9D%E6%BA%90%E9%80%9A%E8%BF%87%E8%87%AA%E5%AE%9A%E4%B9%89%E5%B1%9E%E6%80%A7%E6%92%AD%E6%94%BE%E5%9D%97%E9%9F%B3%E9%A2%91.js

    新增参数

    // 标题播放按钮自定义 Emoji,使用方式同 playEmojiCustom 参数(二者可共存),不使用该参数,填空即可
    const playEmojiCustomHead = '';

    1 回复
  • towfd

    可以正常播放了,但是我好像发现了一点 bug。

    1. 每个块如果只要有了自定义播放按钮,在这个块的任何地方输入或删改任何内容都会将图标吞没。
    2. 原生 emoji,在我的尝试中不会被吞没,但是输入内容后光标会跳回行首,并且会丧失播放功能,但仍然会出现悬停手指。
    3. 无论是自定义还是原生,重启思源或刷新页面后都会导致原图标丧失播放功能,也仍然会出现悬停手指。

    这一点导致我最开始贴入代码时,反复重启思源(之前因为缓存导致了错误,所以我后面贴入代码都重启了)却并没能正常播放,然后我去对照了你增改的地方,发现似乎也是在那几处增加了 convertSrtTimeToSeconds,我本来仍然在想难道仍然是因为有什么地方格式没改完善?但心想你应该对自己代码很了解,如果你和 ai 都只选择了修改这几处,那应该更可能是其他地方有问题。

    于是我又开始尝试,发现我新增加的按钮就能正常播放,但因为按钮后习惯键入空格,以及在换行时,都出现了按钮被吞没的情况,我就又比较了自定义和原生、标题和自带属性的块的不同情况。自定义和原生情况如上,自带属性的块也会出现上述按钮被吞没或光标跳转行首的情况,但不会丧失播放功能(可能因为它的播放机制更简单、更直接?),所以我前几天没发现这个问题,因为光标跳一下我没当回事,光标丢失我也自己补上了,知道今天的重启后标题图标丧失播放功能才提醒我。

    1 回复
  • wilsons 1 1 赞同

    这是因思源块内无法添加自定义元素和自定义属性导致的,详见 Issue #13325 · siyuan-note/siyuan

    又加上 emoji 是字符不好获取点击事件,所以现在放弃 emoji 方案,仅支持自定义 emoji 方案

    新代码如下:

    https://gitee.com/wish163/mysoft/blob/main/%E6%80%9D%E6%BA%90/%E6%80%9D%E6%BA%90%E9%80%9A%E8%BF%87%E8%87%AA%E5%AE%9A%E4%B9%89%E5%B1%9E%E6%80%A7%E6%92%AD%E6%94%BE%E5%9D%97%E9%9F%B3%E9%A2%91.js

    注意:如果同一个标题或块中有多个相同播放按钮,仅第一个添加的生效。

    1 回复
  • towfd 4 评论 via Linux

    功能一切正常!你太厉害了!感谢你这些天在这个问题上花费了这么多时间精力。这几天眼见着代码越来越长,我也越来越不好意思一次又一次地叨扰你,实在太感谢你了!

    不客气,没问题就好。
    wilsons
    @wilsons 我发现排版时使用了超级块的话,当下可以播放,但当刷新后或重启后,按钮又会丧失播放功能(有手指出现),这是因为上面那个 issue 中所说的 span 不能嵌套吗?超级块在思源里也是 span 吗?
    towfd
    @towfd 这是因为思源加载时是以块为单位加载的,使用了超级块后,音频块就变成了嵌套子块,我在 0.0.6 版本做了嵌套块的兼容,你更新下代码试试。
    wilsons 1 1 赞同
    @wilsons 可以了,谢谢你 🙇
    towfd
请输入回帖内容 ...

推荐标签 标签

  • Visio
    1 引用 • 2 回帖
  • Mobi.css

    Mobi.css is a lightweight, flexible CSS framework that focus on mobile.

    1 引用 • 6 回帖 • 764 关注
  • Q&A

    提问之前请先看《提问的智慧》,好的问题比好的答案更有价值。

    9948 引用 • 45190 回帖 • 77 关注
  • 以太坊

    以太坊(Ethereum)并不是一个机构,而是一款能够在区块链上实现智能合约、开源的底层系统。以太坊是一个平台和一种编程语言 Solidity,使开发人员能够建立和发布下一代去中心化应用。 以太坊可以用来编程、分散、担保和交易任何事物:投票、域名、金融交易所、众筹、公司管理、合同和知识产权等等。

    34 引用 • 367 回帖 • 1 关注
  • Shell

    Shell 脚本与 Windows/Dos 下的批处理相似,也就是用各类命令预先放入到一个文件中,方便一次性执行的一个程序文件,主要是方便管理员进行设置或者管理用的。但是它比 Windows 下的批处理更强大,比用其他编程程序编辑的程序效率更高,因为它使用了 Linux/Unix 下的命令。

    125 引用 • 74 回帖
  • 国际化

    i18n(其来源是英文单词 internationalization 的首末字符 i 和 n,18 为中间的字符数)是“国际化”的简称。对程序来说,国际化是指在不修改代码的情况下,能根据不同语言及地区显示相应的界面。

    8 引用 • 26 回帖
  • HTML

    HTML5 是 HTML 下一个的主要修订版本,现在仍处于发展阶段。广义论及 HTML5 时,实际指的是包括 HTML、CSS 和 JavaScript 在内的一套技术组合。

    108 引用 • 295 回帖 • 1 关注
  • 京东

    京东是中国最大的自营式电商企业,2015 年第一季度在中国自营式 B2C 电商市场的占有率为 56.3%。2014 年 5 月,京东在美国纳斯达克证券交易所正式挂牌上市(股票代码:JD),是中国第一个成功赴美上市的大型综合型电商平台,与腾讯、百度等中国互联网巨头共同跻身全球前十大互联网公司排行榜。

    14 引用 • 102 回帖 • 310 关注
  • RemNote
    2 引用 • 16 回帖 • 20 关注
  • 导航

    各种网址链接、内容导航。

    45 引用 • 177 回帖
  • SMTP

    SMTP(Simple Mail Transfer Protocol)即简单邮件传输协议,它是一组用于由源地址到目的地址传送邮件的规则,由它来控制信件的中转方式。SMTP 协议属于 TCP/IP 协议簇,它帮助每台计算机在发送或中转信件时找到下一个目的地。

    4 引用 • 18 回帖 • 631 关注
  • Logseq

    Logseq 是一个隐私优先、开源的知识库工具。

    Logseq is a joyful, open-source outliner that works on top of local plain-text Markdown and Org-mode files. Use it to write, organize and share your thoughts, keep your to-do list, and build your own digital garden.

    7 引用 • 69 回帖 • 5 关注
  • 资讯

    资讯是用户因为及时地获得它并利用它而能够在相对短的时间内给自己带来价值的信息,资讯有时效性和地域性。

    56 引用 • 85 回帖 • 1 关注
  • uTools

    uTools 是一个极简、插件化、跨平台的现代桌面软件。通过自由选配丰富的插件,打造你得心应手的工具集合。

    7 引用 • 27 回帖 • 1 关注
  • 招聘

    哪里都缺人,哪里都不缺人。

    188 引用 • 1057 回帖
  • Swift

    Swift 是苹果于 2014 年 WWDC(苹果开发者大会)发布的开发语言,可与 Objective-C 共同运行于 Mac OS 和 iOS 平台,用于搭建基于苹果平台的应用程序。

    34 引用 • 37 回帖 • 553 关注
  • Telegram

    Telegram 是一个非盈利性、基于云端的即时消息服务。它提供了支持各大操作系统平台的开源的客户端,也提供了很多强大的 APIs 给开发者创建自己的客户端和机器人。

    5 引用 • 35 回帖
  • Vditor

    Vditor 是一款浏览器端的 Markdown 编辑器,支持所见即所得、即时渲染(类似 Typora)和分屏预览模式。它使用 TypeScript 实现,支持原生 JavaScript、Vue、React 和 Angular。

    371 引用 • 1856 回帖 • 1 关注
  • Caddy

    Caddy 是一款默认自动启用 HTTPS 的 HTTP/2 Web 服务器。

    10 引用 • 54 回帖 • 177 关注
  • ReactiveX

    ReactiveX 是一个专注于异步编程与控制可观察数据(或者事件)流的 API。它组合了观察者模式,迭代器模式和函数式编程的优秀思想。

    1 引用 • 2 回帖 • 182 关注
  • SOHO

    为成为自由职业者在家办公而努力吧!

    7 引用 • 55 回帖 • 1 关注
  • 心情

    心是产生任何想法的源泉,心本体会陷入到对自己本体不能理解的状态中,因为心能产生任何想法,不能分出对错,不能分出自己。

    59 引用 • 369 回帖
  • Facebook

    Facebook 是一个联系朋友的社交工具。大家可以通过它和朋友、同事、同学以及周围的人保持互动交流,分享无限上传的图片,发布链接和视频,更可以增进对朋友的了解。

    4 引用 • 15 回帖 • 452 关注
  • React

    React 是 Facebook 开源的一个用于构建 UI 的 JavaScript 库。

    192 引用 • 291 回帖 • 370 关注
  • IPFS

    IPFS(InterPlanetary File System,星际文件系统)是永久的、去中心化保存和共享文件的方法,这是一种内容可寻址、版本化、点对点超媒体的分布式协议。请浏览 IPFS 入门笔记了解更多细节。

    20 引用 • 245 回帖 • 229 关注
  • 学习

    “梦想从学习开始,事业从实践起步” —— 习近平

    172 引用 • 534 回帖
  • MyBatis

    MyBatis 本是 Apache 软件基金会 的一个开源项目 iBatis,2010 年这个项目由 Apache 软件基金会迁移到了 google code,并且改名为 MyBatis ,2013 年 11 月再次迁移到了 GitHub。

    173 引用 • 414 回帖 • 366 关注