node.js重试机制的简单实现

       异常在程序设计的过程中无处不在,也会使我们的程序变得复杂臃肿。简单的do{...}while(1)基本能够实现我们所需要的异常处理,但这个显然不是优雅的node写法。今天自己动手实现一个简单的retry类来实现重试功能。

代码中的异步处理采用co库进行了封装。

retry.js

'use strict';
const maxRetryTimes = 10;
class retry{
    constructor(){
    }
    static *attempt(func, ...args){
        let retry = 0;
        do{
            console.log(`retry time = ${retry}, maxRetryTimes = ${maxRetryTimes}`);
            if(retry++ > maxRetryTimes){
                console.log('return');
                return '';
            }
            let res = yield func(args);
            if(res)
            {
                return res;
            }
        }while(1)
    }
}
module.exports = retry;

测试代码如下:

app.js

'use strict';
const request = require('request');
const co = require('co');
const derived = require('./derived');
var main = function(){
    co(function*(){
        let it = new derived();
        yield it.entry();
    }).then(()=>{
    }, (reason)=>{
        console.log(reason);
    })
}
main();

  base.js 

'use strict'
const co = require('co');
const retry = require('./retry');
class Base{
    constructor(){
        this.timeout = 5000;
    }
    *doSomething(arg){
        return '';
    }
    *getTimeout(){
        return this.timeout;
    }
    *entry(){
        yield retry.attempt(this.doSomething, 'https://www.baidu.com', this);
        console.log(`attempt end....`);
    }
}
module.exports = Base;

derived.js

'use strict';
const co = require('co');
const base = require('./base');
const request = require('co-request');
class derived extends base{
    constructor(){
        super();
    }
    *doSomething(arg){
        try{
            let _this = arg[1];
            let timeout = yield _this.getTimeout();
            console.log(`timeout = ${timeout}`);
            let res = yield request({
                uri: arg[0],
                method:'GET',
                timeout: timeout
            });        
            if(res){
                throw new Error(`test errro`);
            }
            return res.body;
        }catch(error){
            console.log(`error accur: ${error}`);
        }
    }
}
module.exports = derived;
       如果直接使用retry.attempt在基类中调用派生类方法,派生类此方法中this会失效,不能够获取成员变量或者调用基类或子类方法。解决方法是在使用retry.attempt方法封装重试方法时,将this作为参数传递,方法中使用此参数获取成员。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
2. 节流与防抖是针对事件频繁触发而造成性能问题的解决方案。节流是指在一定时间间隔内只执行一次事件回调函数,而防抖是指在事件触发后一定时间内没有再次触发才执行事件回调函数。下面是具体的实现代码: 节流实现代码: ```javascript function throttle(fn, delay) { let timer = null; return function() { const context = this; const args = arguments; if (!timer) { timer = setTimeout(function() { fn.apply(context, args); timer = null; }, delay); } }; } ``` 防抖实现代码: ```javascript function debounce(fn, delay) { let timer = null; return function() { const context = this; const args = arguments; clearTimeout(timer); timer = setTimeout(function() { fn.apply(context, args); }, delay); }; } ``` 3. 设计模式是指在软件开发过程中,为了解决某一类问题而总结出的一套通用的解决方案。它可以提高代码的用性、可维护性和可扩展性。常见的前端设计模式有:单例模式、观察者模式、装饰器模式、工厂模式、策略模式、适配器模式等。 4. 前端常见的设计模式包括: - 单例模式 - 观察者模式 - 装饰器模式 - 工厂模式 - 策略模式 - 适配器模式 - 命令模式 - 代理模式 - 模板方法模式 5. 前端攻击包括:XSS攻击、CSRF攻击、DDoS攻击、SQL注入攻击、网络钓鱼等。防御方案包括:输入校验、防范跨站攻击、使用安全的密码、加强用户身份验证、使用HTTPS、使用CDN等。 6. 利用img进行XSS攻击的方式是通过构造img的src属性,将恶意脚本代码放在url中,由于img标签的src属性不会执行JavaScript代码,因此攻击者需要通过构造url的方式来实现XSS攻击。 7. 数据链路层的主要功能包括:物理寻址、差错控制、帧同步、流量控制、介质访问控制等。 8. 设计批处理多道系统时,首先要考虑的是如何对任务进行调度和分配,以及如何利用多道技术提高系统的资源利用率和吞吐量。 9. Virtual DOM的优势在于它可以通过比较前后两个虚拟DOM树的差异来最小化页面绘的操作,从而提高页面的性能和渲染速度。 10. 文件指纹是在文件名后添加一串hash值来标识文件的唯一性,一般用于浏览器缓存控制和版本管理。可以通过在webpack的output选项中设置filename和chunkFilename来生成文件指纹。 11. 函数柯里化是指将一个接受多个参数的函数转换成一系列接受单个参数的函数的过程。下面是函数柯里化的实现代码: ```javascript function curry(fn) { const len = fn.length; return function curried(...args) { if (args.length >= len) { return fn.apply(this, args); } else { return function(...args2) { return curried.apply(this, args.concat(args2)); }; } }; } ``` 12. JS模拟new操作符的实现可以通过以下步骤实现: - 创建一个新对象 - 将构造函数的原型赋值给新对象的__proto__属性 - 执行构造函数,将this指向新对象 - 如果构造函数有返回值且返回值是对象,则返回该对象,否则返回新对象 以下是代码实现: ```javascript function myNew(constructor, ...args) { const obj = Object.create(constructor.prototype); const result = constructor.apply(obj, args); return result instanceof Object ? result : obj; } ``` 13. V8引擎的垃圾回收机制主要是基于分代式垃圾回收算法和增量式垃圾回收算法。分代式垃圾回收算法将内存分为新生代和老生代两个部分,分别采用不同的垃圾回收策略,新生代采用Scavenge算法,老生代采用Mark-Sweep和Mark-Compact算法。增量式垃圾回收算法则是在垃圾回收过程中采用增量式的方式来进行,避免长时间的阻塞。 14. AMD和CMD规范的区别在于AMD采用异步加载模块的方式,即define函数需要在模块加载完成后再执行,而CMD则采用同步加载模块的方式,即define函数可以在模块定义时就执行。因此,AMD适用于浏览器环境,而CMD适用于Node.js环境。 15. 函数式编程是一种编程范式,它主要关注函数的运算和组合,将函数看作是一等公民,强调使用纯函数和不可变数据结构来实现程序的逻辑。函数式编程可以提高程序的可读性、可维护性和可测性,适用于数据处理、异步编程等领域。常见的函数式编程语言有Haskell、Clojure等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值