请教 JS 中有关 Promise 和回调函数的写法问题

16 天前
 wuoty

在网上浏览的时候看到了下面的一种写法,可以通过新建一个 Promise 对象,在 Promise 对象中绑定回调函数,并获取回调结果,类似与下面这种:


    const img = document.getElementById("bg");
    
    const message = () => {
      return new Promise((resolve, reject) => {
        img.onload = () => {
          resolve("Image loaded successfully"); // 返回回调函数的结果
        };
      });
    };

    const AsyncTest = async () => {
      try {
        const msg = await message();
        console.log(msg);
      } catch (error) {
        console.log(error);
      }
    };

上面的代码确实能够将回调函数的返回值作为 Promise 的调用结果返回。

随后突发奇想,用下面这种方式分别异步调用两次上面代码中的 AsyncTest 的函数:


    // 连续两次调用 AsyncTest 函数
    AsyncTest().then(() => {
      console.log("Async function executed");
    });
    AsyncTest().then(() => {
      console.log("Async function executed");
    });
    

结果发现虽然两次调用,但是只有一个调用有返回,个人的理解是:

这样是否就意味着,第一次的 Promise 始终没有完成,保存在栈空间中,并在 EventLoop 中循环等待 resolve 的调用。 在图片加载完成后拍了堆快照,发现堆中确实留下了一个 Promise 的空间:

请教一下,这是否意味着这块内存空间是否会始终被占用,以及利用 Promise 监听 onload 回调这种写法是否妥当?

2637 次点击
所在节点    JavaScript
28 条回复
amlee
16 天前
真别 rxjs 一直说了,原生 api 就有解决方案,就是 addeventlister 添加事件触发函数,防止重复绑定,建议读读这篇

https://zh.javascript.info/introduction-browser-events#addeventlistener
enjoyCoding
15 天前
这种带有副作用的函数(绑了时间没有解绑)调一次可以, 调两次不行. 因为元素是一个 onload 时间只会在第一次触发, 甚至如果不立刻调用都不会触发. 正常的操作应该写成无副作用的函数, 怎么改成无副作用的函数 每次都新建一个插入 body, 绑定有 addEvent 用完了解绑, 删除元素
Al0rid4l
15 天前
@RedNax 理论上来讲一次性事件当然是可以, 不过个人觉得这个习惯不好, 比如写习惯了一下没注意结果什么事件都用 Promise, 或者同事看见了以为用 Promise 把事件转 awaitable 是正确操作, 把其他事件也跟着这么写, 都很容易埋坑
jerry4718
15 天前
都是说的什么啊,问题明明出在 onload 被覆盖上面啊
jerry4718
15 天前
抱歉,眼瞎了
我觉得用 Promise 来监听 onload 合不合理要分场景来说
如果 img 生命周期很短,比如说封装的工具函数,直接 create 一个 img ,在 onload 里面获取 blob 或者尺寸信息,这时候会不会被覆盖是可控的,个人认为也可以视作“小而美”的
但是如果生命周期比较长,emmmm ,那不好说
,有可能写出来的逻辑都不能符合预期,副作用这东西,要多讨厌有多讨厌
nexo
15 天前
@lolizeppelin rx 是什么
xiyuesaves
15 天前
RedNax
14 天前
@Al0rid4l RxJs 固然方便,但传染性太强,等完全转 RxJs 了,坑就在复杂到爆的面条 RxJS 代码里了,反而更难调试。
我也倒不是反对 RxJs ,不少场景下还是有用的,但大多数情况下我是觉得太重了。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1049064

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX