精华内容
下载资源
问答
  • securtcrt使用了python2.6,往回调时间,还能用 ……。 posted on 2012-03-19 11:13lexus 阅读(...) 评论(...

    ……。

    posted on 2012-03-19 11:13 lexus 阅读(...) 评论(...) 编辑 收藏

    转载于:https://www.cnblogs.com/lexus/archive/2012/03/19/2405784.html

    展开全文
  • 在使用Node.js运行非常多操作时都会使用到回调函数,当中就包含訪问数据库。假设代码中的业务逻辑略微复杂一点,回调一层层嵌套。那么代码非常easy进入Callback Hell,不管对写代码的人还是阅读代码的人,都是精神上...

    因为JavaScript语言异步特性。在使用Node.js运行非常多操作时都会使用到回调函数,当中就包含訪问数据库。假设代码中的业务逻辑略微复杂一点,回调一层层嵌套。那么代码非常easy进入Callback Hell,不管对写代码的人还是阅读代码的人,都是精神上的折磨。

    比如对MySQL的一个事务操作,插入一条posts并插入一条log:

    var title = 'It is a new post';

    connection.beginTransaction(function(err) {

    if (err) { throw err; }

    connection.query('INSERT INTO posts SET title=?', title, function(err, result) {

    if (err) {

    return connection.rollback(function() {

    throw err;

    });

    }

    var log = 'Post ' + result.insertId + ' added';

    connection.query('INSERT INTO log SET data=?', log, function(err, result) {

    if (err) {

    return connection.rollback(function() {

    throw err;

    });

    }

    connection.commit(function(err) {

    if (err) {

    return connection.rollback(function() {

    throw err;

    });

    }

    console.log('success!');

    });

    });

    });

    });

    以上非常简单的一个业务逻辑,已经回调了好几层了,假设略微再复杂一点,那么代码恐怕就无法直视了。

    为了防止发生多层嵌套回调的大坑,能够使用Async.js来解决问题。以下来介绍Async.js结合操作MySQL数据库的使用。

    async.each批量Insert

    假设需求是向log表中插入多条数据。终于返回运行结果,能够使用async.each函数:

    var sqls = [

    "INSERT INTO log SET data='data1'",

    "INSERT INTO log SET data='data2'",

    "INSERT INTO log SET data='data3'"

    ];

    async.each(sqls, function(item, callback) {

    // 遍历每条SQL并运行

    connection.query(item, function(err, results) {

    if(err) {

    // 异常后调用callback并传入err

    callback(err);

    } else {

    console.log(item + "运行成功");

    // 运行完毕后也要调用callback,不须要參数

    callback();

    }

    });

    }, function(err) {

    // 全部SQL运行完毕后回调

    if(err) {

    console.log(err);

    } else {

    console.log("SQL全部运行成功");

    }

    });

    async.each并不能保证运行成功一条SQL语句后再去运行下一条。所以假设有一条运行失败,不会影响到其它语句的运行。

    async.eachSeries按顺序批量Insert

    假设想要实现运行成功上一条语句后再開始运行数组中下一条语句,能够使用eachSeries函数:

    var sqls = [

    "INSERT INTO log SET data='data1'",

    "INSERT INTO log SET data='data2'",

    "INSERT INTO log SET data='data3'"

    ];

    async.eachSeries(sqls, function(item, callback) {

    // 遍历每条SQL并运行

    connection.query(item, function(err, results) {

    if(err) {

    // 异常后调用callback并传入err

    callback(err);

    } else {

    console.log(item + "运行成功");

    // 运行完毕后也要调用callback,不须要參数

    callback();

    }

    });

    }, function(err) {

    // 全部SQL运行完毕后回调

    if(err) {

    console.log(err);

    } else {

    console.log("SQL全部运行成功");

    }

    });

    async.eachSeries保证了SQL的运行顺序。而且当当中一条运行异常。就不会继续运行下一条。

    async.forEachOf获取多条Select语句的查询结果

    async.forEachOf相似于async.each,差别是能够接收Object类型參数。而且会在第二个參数回调函数中传入遍历到的每一项的key,更适合批量运行查询语句并返回结果:

    var sqls = {

    table_a: "select count(*) from table_a",

    table_b: "select count(*) from table_b",

    table_c: "select count(*) from table_c"

    };

    // 用于存放查询结果

    var counts = {};

    async.forEachOf(sqls, function(value, key, callback) {

    // 遍历每条SQL并运行

    connection.query(value, function(err, results) {

    if(err) {

    callback(err);

    } else {

    counts[key] = results[0]['count(*)'];

    callback();

    }

    });

    }, function(err) {

    // 全部SQL运行完毕后回调

    if(err) {

    console.log(err);

    } else {

    console.log(counts);

    }

    });

    运行结果:

    { table_a: 26, table_b: 3, table_c: 2 }

    async.map简化获取多条Select语句的查询结果

    上面的async.forEachOf获取多条Select语句的查询结果的代码能够使用async.map函数简化成这样:

    var sqls = {

    table_a: "select count(*) from table_a",

    table_b: "select count(*) from table_b",

    table_c: "select count(*) from table_c"

    };

    async.map(sqls, function(item, callback) {

    connection.query(item, function(err, results) {

    callback(err, results[0]['count(*)']);

    });

    }, function(err, results) {

    if(err) {

    console.log(err);

    } else {

    console.log(results);

    }

    });

    运行结果:

    { table_a: 26, table_b: 3, table_c: 2 }

    async.series按顺序运行多条任务

    Async.js非常有用的一个功能就是流程控制。回到本文刚開始的那个开启事务运行Insert的样例。每一步都须要上一步运行成功后才干运行,非常easy掉进回调大坑中。

    以下有用async.series函数来优化流程控制,让代码更优雅:

    var title = 'It is a new post';

    // 用于在posts插入成功后保存自己主动生成的ID

    var postId = null;

    // function数组,须要运行的任务列表,每一个function都有一个參数callback函数而且要调用

    var tasks = [function(callback) {

    // 开启事务

    connection.beginTransaction(function(err) {

    callback(err);

    });

    }, function(callback) {

    // 插入posts

    connection.query('INSERT INTO posts SET title=?', title, function(err, result) {

    postId = result.insertId;

    callback(err);

    });

    }, function(callback) {

    // 插入log

    var log = 'Post ' + postId + ' added';

    connection.query('INSERT INTO log SET data=?', log, function(err, result) {

    callback(err);

    });

    }, function(callback) {

    // 提交事务

    connection.commit(function(err) {

    callback(err);

    });

    }];

    async.series(tasks, function(err, results) {

    if(err) {

    console.log(err);

    connection.rollback(); // 错误发生事务回滚

    }

    connection.end();

    });

    async.waterfall按顺序运行多条任务而且下一条任务可获取上一条任务的运行结果

    上面使用async.series按顺序运行多条任务。可是非常多情况下运行一个任务的时候须要用到上一条任务的相关数据,比如插入一条数据到posts表后,会自己主动生成ID,下一步插入日志会用到这个ID,假设使用async.series函数就须要定义一个变量var postId来存储这个ID,此时可使用async.waterfall来替代async.series。

    var title = 'It is a new post';

    var tasks = [function(callback) {

    connection.beginTransaction(function(err) {

    callback(err);

    });

    }, function(callback) {

    connection.query('INSERT INTO posts SET title=?', title, function(err, result) {

    callback(err, result.insertId); // 生成的ID会传给下一个任务

    });

    }, function(insertId, callback) {

    // 接收到上一条任务生成的ID

    var log = 'Post ' + insertId + ' added';

    connection.query('INSERT INTO log SET data=?

    ', log, function(err, result) {

    callback(err);

    });

    }, function(callback) {

    connection.commit(function(err) {

    callback(err);

    });

    }];

    async.waterfall(tasks, function(err, results) {

    if(err) {

    console.log(err);

    connection.rollback(); // 错误发生事务回滚

    }

    connection.end();

    });

    async.series获取多条SQL的结果

    // tasks是一个Object

    var tasks = {

    table_a: function(callback) {

    connection.query('select count(*) from table_a', function(err, result) {

    callback(err, result[0]['count(*)']); // 将结果传入callback

    });

    },

    table_b: function(callback) {

    connection.query('select count(*) from table_b', function(err, result) {

    callback(err, result[0]['count(*)']);

    });

    },

    table_c: function(callback) {

    connection.query('select count(*) from table_c', function (err, result) {

    callback(err, result[0]['count(*)']);

    });

    }

    };

    async.series(tasks, function(err, results) {

    if(err) {

    console.log(err);

    } else {

    console.log(results);

    }

    connection.end();

    });

    运行结果:

    { table_a: 26, table_b: 3, table_c: 2 }

    以上是Async.js操作数据库常常会用到的一些样例,用上它的话就不再须要操心异步回调的坑了。Async.js不只能够用于数据库操作,其它用到异步回调函数的地方都能够使用。比如文件读写等,本文不过通过数据库操作为例来介绍Async.js基本使用方法。它相同也能够运用到其它须要它的地方。除了上面介绍的几个函数外。Async.js还提供了一些其它有用的函数,能够參考文档灵活使用。

    展开全文
  • 像这样创建一个触发器.DELIMITER $$CREATE TRIGGER ad_mytable_each AFTER DELETE ON MyTable FOR EACH ROWBEGIN#write code that trigger After delete (hence the "ad_" prefix)#For table MyTable (The _MyTable_...

    像这样创建一个触发器.

    DELIMITER $$

    CREATE TRIGGER ad_mytable_each AFTER DELETE ON MyTable FOR EACH ROW

    BEGIN

    #write code that trigger After delete (hence the "ad_" prefix)

    #For table MyTable (The _MyTable_ middle)

    #On each row that gets inserted (_each suffix)

    #

    #You can see the old delete values by accesing the "old" virtual table.

    INSERT INTO log VALUES (old.id, 'MyTable', old.field1, old.field2, now());

    END$$

    DELIMITER ;

    INSERT,DELETE,UPDATE有触发器

    他们可以在行动之前或之后开火.

    操作之前的触发器可以通过强制错误来取消操作,如此.

    CREATE TRIGGER bd_mytable_each BEFORE DELETE ON MyTable FOR EACH ROW

    BEGIN

    #write code that trigger Before delete (hence the "db_" prefix)

    declare DoError Boolean;

    SET DoError = 0;

    IF old.id = 1 THEN SET DoError = 1; END IF;

    IF (DoError = 1) THEN SELECT * FROM Table_that_does_not_exist_to_force_error;

    #seriously this example is in the manual.

    END$$

    DELIMITER ;

    这将阻止删除记录1.

    之前的UPDATE触发器甚至可以更改更新的值.

    CREATE TRIGGER bu_mytable_each BEFORE UPDATE ON MyTable FOR EACH ROW

    BEGIN

    IF new.text = 'Doon sucks' THEN SET new.text = 'Doon rules';

    END$$

    DELIMITER ;

    希望你能快乐起来.

    展开全文
  • 还可以实现DisposableBean接口,来回调bean销毁时候执行的方法,这个接口有一个destroy方法,生命周期是是destroy----bean销毁---自定义的destroy方法 SimpleBean.java package ch5.destroy;import org.spring...

    除了自定义的destroy-method.还可以实现DisposableBean接口,来回调bean销毁时候执行的方法,这个接口有一个destroy方法,生命周期是是destroy----bean销毁---自定义的destroy方法 

     

    SimpleBean.java

     

    package ch5.destroy;

    import org.springframework.beans.factory.DisposableBean;
    import org.springframework.beans.factory.InitializingBean;

    public class SimpleBean implements InitializingBean,DisposableBean {
      
    public void afterPropertiesSet() throws Exception {
            System.out.println(
    "this is info from afterpropertiesSet from SimpleBean");
        }

    private  String name;
      
    private String sex;
      
    private String age;
      
    public void destroyMethod(){
          System.out.println(
    "this is info from customer destroy method");
      }

      
    public void destroy(){
          System.out.println(
    "this is info from destroy method");
      }

    public String getAge() {
        
    return age;
    }

    public void setAge(String age) {
        
    this.age = age;
    }

    public String getName() {
        
    return name;
    }

    public void setName(String name) {
        
    this.name = name;
    }

    public String getSex() {
        
    return sex;
    }

    public void setSex(String sex) {
        
    this.sex = sex;
    }

    }

     

    配置文件:

     

    <?xml version="1.0" encoding="UTF-8"?>
    <beans
        
    xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi
    ="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation
    ="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">

    <bean id="SimpleBean" class="ch5.destroy.SimpleBean" destroy-method="destroyMethod">
    <property name="name">
        
    <value>gaoxiang</value>
      
    </property>
    <property name="sex">
       
    <value>male</value>
    </property>
    <property name="age">
        
    <value>26</value>
      
    </property>
    </bean>


    </beans>

     

    测试代码:

     

    package ch5.destroy;

    import java.io.File;

    import org.springframework.beans.factory.BeanFactory;
    import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
    import org.springframework.beans.factory.support.BeanDefinitionRegistry;
    import org.springframework.beans.factory.xml.XmlBeanFactory;
    import org.springframework.core.io.FileSystemResource;

    public class TestSpring{
      
    public static void main(String args[])  throws Exception{
          
    //获取bean factory
          ConfigurableListableBeanFactory factory=(ConfigurableListableBeanFactory)getBeanFactory();  //使用子beanFactory
         
         
          SimpleBean bean1
    =(SimpleBean)factory.getBean("SimpleBean");
          
          System.out.println(
    "before destroy");
          factory.destroySingletons();
          System.out.println(
    "after destory");
        
      }

      
    public static BeanFactory getBeanFactory(){
          
    //获取bean factory
          String realpath="";
       
             
    //加载配置项
          realpath=System.getProperty("user.dir")+File.separator+"src"+File.separator+"ch5/destroy"+File.separator+"applicationContext.xml";
      
         
          ConfigurableListableBeanFactory  factory
    =new XmlBeanFactory(new FileSystemResource(realpath));
          
          
    return factory;
      }

    }

     

    结果:

    this is info from afterpropertiesSet from SimpleBean
    before destroy
    this is info from destroy method
    this is info from customer destroy method

    after destory

    展开全文
  • 使用实现了ConfigurableListableBeanFactory接口的XmlBeanFactory ,可以使用destroySingletons方法通知销毁所有的singleton实例,这时候,如果我们为bean定义了destroy-methd属性,就会进行调用,我们可以在其中...
  • 看了下goc里面设置回调函数的例子,里面的回调函数的参数都是简单的类型,char *和int,今天在此举一个结构体为回调参数的例子。 头文件为GoDll.h,内容如下: #ifndef __GO_DLL_H__ #define __GO_DLL_H__ /*C代...
  • 怎么SetTimer的回调函数传递参数
  • android 回调从AsyncTaskActivity传数据

    千次阅读 2016-09-05 14:03:30
    ( //设置回调借口 public interface callBack{ void setItem(Item i); } ( 2 //给LoadTask添加设置回调的方法 public void setCallBack(callBack callback){ this.callBack = callback; }( 3
  • 股市波动非常大,所以是高风险的...一般股市的回调有两种:首先是股票市场变大,并且获利后股票市场回调,此时的回调是出货的回调,因此此时是危险的信号。 二是强回调,这种回调一般伴随着缩量,这是市场主力主动性...
  • 回调函数

    2019-08-21 22:42:35
    回调函数 js 是同步的语言;执行顺序是冲上下的 回调函数是异步的 代码的执行顺序分为:同步 异步 同步 弊端:会发生执行阻塞 异步不会发生阻塞 异步:未来某一时刻需要执行的代码,优先执行,同步是...
  • 接口回调

    2018-01-11 11:33:58
    其实接口回调的关键点就是,接口在哪个类里面实现了,这个实现就是new 对象,也就是实例化了一个匿名内部类,同时把这个对象放到内存里,现在这个对象就相当于一个信使,我只要在别的类里面能够得到这个信使,他的...
  • 关于回调理解

    2016-07-14 19:10:24
    1.回调分为回调跟异步回调 1.1回调 1.2异步回调 如ajax,新建线程去跑程序,如阻塞队列,发起请求不等相应继续下执行,主线程不会去等待
  • Promise处理异步回调

    2021-01-14 09:13:40
    ​ node.js 采用异步回调的方式来处理需要等待的事件,使得代码会继续下执行,不用在某个地方等待着。但是当有很多回调的时候,比如这个回调执行完需要去执行下个回调,然后接着再执行下个回调,这样就会造成回调...
  • 回调函数详解

    2020-01-07 16:51:33
    1.1 回调函数在开发中特别常用,就是一个通过函数指针调用的函数。 1.2 很多人说不懂,说找不到函数原型实现的地方,我想应该是不懂函数指针(不懂函数指针的可先去补补再下看)。 2.找回调原型 2.1 回调函数...
  • 我正试图编写python代码来调用dll函数,并停留在下面的函数上,我认为这与typedef回调函数或函数指针有关。我已经测试了下面的代码,当调用回调函数时,python崩溃(窗口通知——python.exe停止响应),没有调试消息。...
  • (1)同步调用同步调用是最基本并且最简单的一种调用方式,类A的方法a()调用类B的方法b(),一直等待b()方法执行完毕,a()方法继续下走。这种调用方式适用于方法b()执行时间不长的情况,因为b()方法执行时间一长或者...
  • Python回调函数

    2020-02-02 18:47:41
    打个比方,有一家旅馆提供叫醒服务,但是要求旅客自己决定叫醒的方法。...而旅客告诉旅馆怎么叫醒自己的动作,也就是把回调函数传入库函数的动作,称为登记回调函数(to register a callback func...
  • windows核心编程 p304,是不是可以用这种方法搞个线程池?。。。
  • 逼不得已,只能硬着头皮就着官方的文档一步步的下做,最终终于实现是回调模式的第一步:URL验证。现将代码共享出来,供各位新手借鉴,同时的后续开发,可以共同交流、学习。1.要开启企业号的回调模式,首先要进行...
  • 无论使用何种语言开发,必然存在模块之间的调用,调用的方式分为几种:(1)同步调用同步调用是最基本并且最简单的一种调用方式,类A的方法a()调用类B的方法b(),一直等待b()方法执行完毕,a()方法继续下走。...
  • java 回调机制

    2017-07-07 13:39:56
    而你反过来又调用我的方法通常称之为回调函数,放在一个专门的接口里面,需要回调机制的类就需要实现这个接口,而且在我调用你的方法的时候,需要把我或者我的某个实例再传递给你,你再通过这个实例调用我的回调函数...
  • 无论使用何种语言开发,必然存在模块之间的调用,调用的方式分为几种:(1)同步调用同步调用是最基本并且最简单的一种调用方式,类A的方法a()调用类B的方法b(),一直等待b()方法执行完毕,a()方法继续下走。...
  • 后台传多值问题 function newstatust(p6id,referencenumber,taskId) { $.ajax({ type : "post", url : "newstatus.action", data : {p6OrderId:p6id,referencenumber:...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 989
精华内容 395
关键字:

往回调