V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
magicdawn
V2EX  ›  Node.js

promise.timeout 现在支持资源清理了

  •  
  •   magicdawn · 2016-06-02 09:13:23 +08:00 · 2958 次点击
    这是一个创建于 3121 天前的主题,其中的信息可能已经有所发展或是发生改变。

    原文发在 CNodejs.org https://cnodejs.org/topic/574f88811176fe255bb8d7e3


    promise.timeout 是我之前发的 promise 工具包 系列 https://cnodejs.org/topic/573b2d64fcf698421d20359d 中的一个

    promise.timeout

    promise.timeout 给一个 async function 加上超时支持, 就是你原来的返回值是一 promise, 加上 timeout 支持后, 超时了就会以一个 timeout error reject 掉 https://github.com/magicdawn/promise.timeout

    function test(){
      // 20ms 后去 resolve
      return new Promise(resolve => {
        setTimeout(()=>{ resolve(20) }, 20);
      });
    }
    
    const ptimeout = require('promise.timeout');
    const test10 = ptimeout(test, 10); // test 方法, 10ms 超时
    
    // e instanceof ptimeout.TimeoutError
    test10().then(function(res){
      console.log(res);
    }, function(e){
      console.error(e)
    });
    

    问题

    这里其实是这样的 untitled1.png

    原来 test() 和 超时定时器比谁先跑完, 10ms 的超时定时器先跑完. 于是 test10() 的返回值以 ptimeout.TimeoutError 实例 reject 掉 但是这里有个问题, promise 没有取消机制, 原来的 promise 还在跑...

    onCancel

    function test(onCancel){
      // 20ms 后去 resolve
      return new Promise(resolve => {
        const t = setTimeout(()=>{ resolve(20) }, 20);
    	onCancel && onCancel(() => {
    	  clearTimeout(t); // 资源清理
    	});
      });
    }
    
    const ptimeout = require('promise.timeout');
    const test10 = ptimeout(test, 10, true); // test 方法, 10ms 超时, 加了一个 cancel = true 参数
    
    // e instanceof ptimeout.TimeoutError
    test10().then(function(res){
      console.log(res);
    }, function(e){
      console.error(e)
    });
    

    如果给 ptimeout 的第三个参数传 true, 表示打开 cancel 支持, 这样

    • test10 在 调用 test 的时候, 会多传一个 onCancel 参数
    • test 可以拿 onCancel 注册回调, 在超时器先跑完的情况下, 可以去清理你这个 promise 所占有的资源
    • 然后在没超时的情况下, test() 的返回值可以清理掉超时定时器, 避免因为 timer 引起的进程不退出, 也是避免调用那个清理操作.

    其实就是两个 race, 谁先跑完就把另一个清理掉... 这里拿 timer 举例的, 还可以看看 网络请求 / 文件访问这种, 如果超时, 可以 abort 网络请求, close 文件. 实例请看 https://github.com/magicdawn/yun-playlist-downloader

    目前尚无回复
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3701 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 04:16 · PVG 12:16 · LAX 20:16 · JFK 23:16
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.