利用异步事件解决同一事件多次调用的问题
发布于 8 年前 作者 iyuq 4919 次浏览 来自 分享

最近在阅读朴大的《深入浅出Node.js》这本书籍,朴大写了一段伪代码,介绍如遇到并发量特别大的同一条SQL语句查询可以用如下方式实现:

var events = require("events");
var proxy = new events.EventEmitter();
var status = "ready";
var select = function (callback) {
    proxy.once("selected", callback);
    if (status === "ready") {
        status = "pending";
        db.select("SQL", function (results) {
            proxy.emit("selected", results);
            status = "ready";
        });
    }
};

这段代码利用事件队列的once方法,当有一次新的查询请求过来时先将查询成功的回调函数压入selected事件的事件堆中,然后判断状态,如果事件的状态是没有开始的状态,则调用查询的异步方法,在回调函数中再触发selected事件。 我利用这段代码写了一段类似可执行的程序:

var EventEmitter = require('events').EventEmitter;
var proxy = new EventEmitter();
proxy.setMaxListeners(0);
var status = "ready";
var doSomething = function (callback) {
    proxy.once("selected", callback);
    console.log("add a listener!");
    if (status === "ready") {
        status = "pending";
        setTimeout(function () {
            proxy.emit("selected");
            status = "ready";
            console.log("resolved");
        }, 1000);
    };
};

for (var i = 0; i < 20; i++) {
    setTimeout(function (i) {
        return (function (i) {
            doSomething(function () {
                console.log(i)
            });
        })(i)
    }, 100 * i, i);
};

首先,我用setTimeout(func, 1000)注册一个1s后发生的事件来模拟查询SQL这类异步事件,同时,利用循环,每隔100ms注册一个doSomething的事件,事件的回调函数就是将注册事件的序号打印出来,由于是异步回调,我们得利用闭包来将i封装。 这段代码运行的结果将是类似如下: 运行结果 希望能帮助大家理解!第一次写Blog,可能语句不太通顺,请见谅!

回到顶部