Node.js 实现回调

1 向回调函数传递额外的参数

大部分回调函数都有传递给它们的自动函数,如错误或结果缓冲区。使用回调函数时,常见一个问题:如何从调用函数给回调函数传递额外的参数。一个方法就是在一个匿名函数中实现该参数,然后用来自匿名函数的参数调用回调函数。

示例:

var events = require('events');
var util = require('util');

function CarShow() {
    this.showCar = function (make) {
        this.emit('showed', make);
    }
}

util.inherits(CarShow, events.EventEmitter);

function logCar(make) {
    console.log('我看见了一辆%s', make);
}

function logColorCar(make, color) {
    console.log('我看见了一辆%s', color, make);
}

var carShow = new CarShow();
carShow.on('showed', logCar);
carShow.on('showed', function (make) {
    var colors = ['白色', '黑色', '红色', '蓝色'];
    var color = colors[Math.floor(Math.random() * 4)];
    logColorCar(make, color);     
});

carShow.showCar("奔驰");

输出:

我看见了一辆奔驰
我看见了一辆白色 奔驰

可以看到定义的第二个事件处理程序用了一个匿名函数。随机选择的颜色被传递给函数logColorCar调用。

2 在异步回调中实现闭包

闭包表示一个变量被绑定到一个函数的作用域,但不绑定到它的父函数的作用域(也可以简单理解成:闭包内的函数可以使用父函数的变量,但是父函数不可以使用它的变量)。
如果某个函数需要访问父函数的作用域的变量,就需要闭包。

function logCar(msg, callback) {
    process.nextTick(function () {//这样才能异步回调
        callback(msg);
    });
}

var cars = ['奔驰', '宝马', '大众', '红旗'];

for (var index in cars) {
    var msg = cars[index];
    logCar(msg, function () {
        console.log(msg);
    })
}

for (var index in cars) {
    var msg = cars[index];
    (function (index) {
        var msg = cars[index];
        logCar(msg, function () {
            console.log(msg);
        })
    })(index);
}

输出:

红旗
红旗
红旗
红旗
奔驰
宝马
大众
红旗

在前端,可能会有这样的需求:有若干方块,当鼠标移入某个方块上时,这个方块及它之前的所有方块要发生一些样式上的变化。这个函数的实现便需要闭包:

var oDivs = document.getElementsByTagName('div');

for (var i = 0; i < oDivs.length; i++) {
    (function (index) {
        oDivs[i].onmouseover = function () {
            for (var j = 0; j <= index; j++) {
                oDivs[j].style.background = "pink";
            }
        }

        oDivs[i].onmouseout = function () {
            for (var j = 0; j <= index; j++) {
                oDivs[j].style.background = "white";
            }
        }
    })(i);
}

3 链式回调

使用异步函数时,如果两个函数都在事件队列上,则无法保证它们的执行顺序。解决办法:让来自异步函数的回调再次调用该函数,直到没有工作要做,以执行链式回调。这样异步函数在事件队列上不会超过一次。

function logCar(car, callback) {
    console.log("我看见了一辆%s", car);

    if (cars.length) {
        process.nextTick(function () {
            callback();
        });
    }
}

function logCars(cars) {
    var car = cars.pop();

    logCar(car, function () {
        logCars(cars);
    })
}

var cars = ['奔驰', '宝马', '大众', '红旗'];
logCars(cars);

输出:

我看见了一辆红旗
我看见了一辆大众
我看见了一辆宝马
我看见了一辆奔驰
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值