V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a JavaScript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
JavaScript 权威指南第 5 版
Closure: The Definitive Guide
zmz980126
V2EX  ›  JavaScript

求教一个 js 的问题,入门菜鸡

  •  
  •   zmz980126 · 2021-04-28 09:34:22 +08:00 · 3527 次点击
    这是一个创建于 1307 天前的主题,其中的信息可能已经有所发展或是发生改变。

    大概场景就是有一段源代码,不修改它

    //源代码
    ...
    function a(){
    console.log("111");
    }
    ...
    a();
    console.log("333");
    ...
    //新代码
    function b(){
     console.log("222");
    }
    

    大概就是想在 a 调用完立刻调用 b 输出结果顺序为 111 222 333

    扩展一步,如果是调用前能办到吗,即在执行 a 前先把 b 执行

    (不知道 a 被调用了几次,但想把 b 绑定在 a 上)

    可以在 b 中直接修改 a 的运行时代码吗?

    感谢~

    27 条回复    2021-04-29 16:20:08 +08:00
    yunyuyuan
        1
    yunyuyuan  
       2021-04-28 09:39:34 +08:00
    有点不知所云
    xiaoxinshiwo
        2
    xiaoxinshiwo  
       2021-04-28 09:43:57 +08:00
    回调函数
    kop1989
        3
    kop1989  
       2021-04-28 09:44:20 +08:00
    我揣测一下,看到 lz 说先执行 b,lz 是不是想讨论 b 是异步的问题。

    假设 a 、b 都是同步(同线程)的情况下:
    a();b();输出 333 。

    假设 a 、b 是异步的情况下:
    用 promise 或者 async 、await 语法糖。
    joesonw
        4
    joesonw  
       2021-04-28 09:44:42 +08:00
    var _a = a; a = function() { _a(); b(); }
    kop1989
        5
    kop1989  
       2021-04-28 09:45:44 +08:00
    如果不太懂 promise 或者 async 、await,也可以按照#2 说的,b 的传入参数里加入 callback 函数。
    既把执行完 b 需要做的代码直接当作参数传入 b 。b 最后执行。
    Kasumi20
        6
    Kasumi20  
       2021-04-28 09:53:02 +08:00
    你要是能把 a()改成下面这样的话,我还有点办法
    window.a = function (){
    console.log("111");
    }
    shakukansp
        7
    shakukansp  
       2021-04-28 09:53:11 +08:00
    第一种情况先执行 A 再执行 B 只要改成 promise 或者 async await 就行了
    第二种情况可以用修饰器
    @b
    function a() {}
    让 b 在 a 之前执行
    touchwithe
        8
    touchwithe  
       2021-04-28 09:55:08 +08:00 via iPhone
    这不就是 py 中的装饰器么?参考四楼,把 a 覆盖就行了
    Biwood
        9
    Biwood  
       2021-04-28 10:45:05 +08:00 via iPhone
    函数劫持,见 4 楼
    AsisA
        10
    AsisA  
       2021-04-28 11:05:15 +08:00
    1. 控制执行顺序的话,如果是同步代码,那么直接按照执行顺序排列函数调用顺序就行
    2. 如果是异步代码,可以用 Promise,Async/Await,Rxjs 等方案
    3. 第三个问题用装饰器即可
    yamedie
        11
    yamedie  
       2021-04-28 11:17:30 +08:00
    面向切面编程
    yaphets666
        12
    yaphets666  
       2021-04-28 12:08:37 +08:00
    js 考察代码执行顺序的都是在考察微任务宏任务 event loop 不是用 settimeout 就是用 promise 解决
    DrakeXiang
        13
    DrakeXiang  
       2021-04-28 12:46:38 +08:00
    楼主说的是有一段源代码不能修改,然后加新代码在源代码顺序执行的过程中插入执行,这是不可能的
    ciaoly
        14
    ciaoly  
       2021-04-28 13:02:33 +08:00 via Android
    或许可以通过 window 的某些事件实现吧。。。
    Augi
        15
    Augi  
       2021-04-28 13:23:52 +08:00 via iPhone
    无论怎么样,必须在源代码上做修改。
    hronro
        16
    hronro  
       2021-04-28 13:54:21 +08:00
    想在运行时修改原函数内的代码,这是不可能的。
    如果真的可以做到,那所有的广告 JS SDK 都可以去修改网站本身的函数,给里面注入各种后门,那得多可怕。
    unco020511
        17
    unco020511  
       2021-04-28 15:07:27 +08:00
    如果是 java,可以用切面或者热修复之类的,但是 js,我就不知道有没有这中操作了
    nekochyan
        18
    nekochyan  
       2021-04-28 15:20:56 +08:00
    如果你能在 b 中拿到 a 这个对象 这就好办,就像四楼一样,拿不到那就没办法
    lllllliu
        19
    lllllliu  
       2021-04-28 16:54:01 +08:00
    责任链包装一哈。一路 next,
    使用或者不是使用箭头函数改变上下文。
    gesse
        20
    gesse  
       2021-04-28 17:33:15 +08:00
    @kop1989
    你太高看楼主了。
    zmz980126
        21
    zmz980126  
    OP
       2021-04-29 09:13:42 +08:00
    @joesonw 这么写,我有一个问题
    如果 a 的调用在这段代码之前执行,这个覆盖不就执行不到吗
    zmz980126
        22
    zmz980126  
    OP
       2021-04-29 09:14:44 +08:00
    @gesse 是的,太高看我了,刚开始学 js
    zmz980126
        23
    zmz980126  
    OP
       2021-04-29 09:16:34 +08:00
    @Kasumi20 如果是是 window.a 的话,怎么做呢,拜谢~
    zmz980126
        24
    zmz980126  
    OP
       2021-04-29 09:34:34 +08:00
    其实最初的场景是一个课程学习网站,每过一段时间会出现一个确认框确认你是否真的在看,挺烦人,所以我就写了个油猴脚本(因为刚开始学 js 想试试),就遇到了这个问题想在它每次执行 showwarn()后执行一个 onclick 的 unshow() (当然,原来的函数名肯定不叫这个) ,最后没解决,就每隔一段时间 t 检测一下,那个改变的 html 元素,然后改变就 unshow,感觉写的很蠢
    如果 t 太长,那如果出现确认框说不定也要等很长时间,如果 t 太短那就会一直执行这个检测,感觉很影响效率(且蠢)
    然后就有了这个问题
    xingheng
        25
    xingheng  
       2021-04-29 13:27:55 +08:00
    function decorator
    oldshensheep
        26
    oldshensheep  
       2021-04-29 14:54:04 +08:00
    MutationObserver 可以监听 dom 的变化,然后调用你的 unshow()函数就行了
    https://developer.mozilla.org/zh-CN/docs/Web/API/MutationObserver/MutationObserver
    如果你一开始把你要干什么说出来大家就明白了。

    如果不修改 a 的话应该不能实现你的要求。
    KiZuNaYa
        27
    KiZuNaYa  
       2021-04-29 16:20:08 +08:00
    加个定时器不就好了?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1042 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 19:34 · PVG 03:34 · LAX 11:34 · JFK 14:34
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.