@@ -579,15 +579,17 @@ RedisClient.prototype.return_reply = function (reply) {
579
579
580
580
if ( command_obj && ! command_obj . sub_command ) {
581
581
if ( typeof command_obj . callback === "function" ) {
582
- if ( this . options . detect_buffers && command_obj . buffer_args === false && 'exec' !== command_obj . command ) {
583
- // If detect_buffers option was specified, then the reply from the parser will be Buffers.
584
- // If this command did not use Buffer arguments, then convert the reply to Strings here.
585
- reply = reply_to_strings ( reply ) ;
586
- }
582
+ if ( 'exec' !== command_obj . command ) {
583
+ if ( this . options . detect_buffers && command_obj . buffer_args === false ) {
584
+ // If detect_buffers option was specified, then the reply from the parser will be Buffers.
585
+ // If this command did not use Buffer arguments, then convert the reply to Strings here.
586
+ reply = reply_to_strings ( reply ) ;
587
+ }
587
588
588
- // TODO - confusing and error-prone that hgetall is special cased in two places
589
- if ( reply && 'hgetall' === command_obj . command ) {
590
- reply = reply_to_object ( reply ) ;
589
+ // TODO - confusing and error-prone that hgetall is special cased in two places
590
+ if ( reply && 'hgetall' === command_obj . command ) {
591
+ reply = reply_to_object ( reply ) ;
592
+ }
591
593
}
592
594
593
595
command_obj . callback ( null , reply ) ;
@@ -993,92 +995,88 @@ Multi.prototype.hmset = Multi.prototype.HMSET = function (key, args, callback) {
993
995
return this ;
994
996
} ;
995
997
998
+ Multi . prototype . send_command = function ( command , args , cb ) {
999
+ var self = this ;
1000
+ this . _client . send_command ( command , args , function ( err , reply ) {
1001
+ if ( err ) {
1002
+ if ( cb ) {
1003
+ cb ( err ) ;
1004
+ } else {
1005
+ self . errors . push ( err ) ;
1006
+ }
1007
+ }
1008
+ } ) ;
1009
+ } ;
1010
+
996
1011
Multi . prototype . exec = Multi . prototype . EXEC = function ( callback ) {
997
1012
var self = this ;
998
- var errors = [ ] ;
999
- var wants_buffers = [ ] ;
1013
+ this . errors = [ ] ;
1014
+ this . callback = callback ;
1015
+ this . wants_buffers = new Array ( this . queue . length ) ;
1000
1016
// drain queue, callback will catch "QUEUED" or error
1001
- // TODO - get rid of all of these anonymous functions which are elegant but slow
1002
- this . queue . forEach ( function ( args , index ) {
1003
- var command = args [ 0 ] , obj , i , il , buffer_args ;
1017
+ for ( var index = 0 ; index < this . queue . length ; index ++ ) {
1018
+ var args = this . queue [ index ] . slice ( ) ;
1019
+ var command = args . shift ( ) ;
1020
+ var cb ;
1004
1021
if ( typeof args [ args . length - 1 ] === "function" ) {
1005
- args = args . slice ( 1 , - 1 ) ;
1006
- } else {
1007
- args = args . slice ( 1 ) ;
1022
+ cb = args . pop ( ) ;
1008
1023
}
1009
1024
// Keep track of who wants buffer responses:
1010
- buffer_args = false ;
1011
- for ( i = 0 , il = args . length ; i < il ; i += 1 ) {
1025
+ this . wants_buffers [ index ] = false ;
1026
+ for ( var i = 0 ; i < args . length ; i += 1 ) {
1012
1027
if ( Buffer . isBuffer ( args [ i ] ) ) {
1013
- buffer_args = true ;
1028
+ this . wants_buffers [ index ] = true ;
1029
+ break ;
1014
1030
}
1015
1031
}
1016
- wants_buffers . push ( buffer_args ) ;
1017
- if ( args . length === 1 && Array . isArray ( args [ 0 ] ) ) {
1018
- args = args [ 0 ] ;
1019
- }
1020
- if ( command === 'hmset' && typeof args [ 1 ] === 'object' ) {
1021
- obj = args . pop ( ) ;
1022
- Object . keys ( obj ) . forEach ( function ( key ) {
1023
- args . push ( key ) ;
1024
- args . push ( obj [ key ] ) ;
1025
- } ) ;
1026
- }
1027
- this . _client . send_command ( command , args , function ( err , reply ) {
1028
- if ( err ) {
1029
- var cur = self . queue [ index ] ;
1030
- if ( typeof cur [ cur . length - 1 ] === "function" ) {
1031
- cur [ cur . length - 1 ] ( err ) ;
1032
- } else {
1033
- errors . push ( err ) ;
1034
- }
1035
- }
1036
- } ) ;
1037
- } , this ) ;
1032
+ this . send_command ( command , args , cb ) ;
1033
+ }
1038
1034
1039
- // TODO - make this callback part of Multi.prototype instead of creating it each time
1040
- return this . _client . send_command ( "exec" , [ ] , function ( err , replies ) {
1041
- if ( err && ! err . code ) {
1042
- if ( callback ) {
1043
- errors . push ( err ) ;
1044
- callback ( errors ) ;
1045
- return ;
1035
+ this . _client . send_command ( 'exec' , [ ] , function ( err , replies ) {
1036
+ self . execute_callback ( err , replies ) ;
1037
+ } ) ;
1038
+ } ;
1039
+
1040
+ Multi . prototype . execute_callback = function ( err , replies ) {
1041
+ var i , reply , args ;
1042
+
1043
+ if ( err ) {
1044
+ if ( err . code !== 'CONNECTION_BROKEN' ) {
1045
+ if ( this . callback ) {
1046
+ this . errors . push ( err ) ;
1047
+ this . callback ( this . errors ) ;
1046
1048
} else {
1047
- self . _client . emit ( 'error' , err ) ;
1049
+ // Exclude CONNECTION_BROKEN so that error won't be emitted twice
1050
+ this . _client . emit ( 'error' , err ) ;
1048
1051
}
1049
1052
}
1053
+ return ;
1054
+ }
1050
1055
1051
- var i , il , reply , to_buffer , args ;
1052
-
1053
- if ( replies ) {
1054
- for ( i = 1 , il = self . queue . length ; i < il ; i += 1 ) {
1055
- reply = replies [ i - 1 ] ;
1056
- args = self . queue [ i ] ;
1057
- to_buffer = wants_buffers [ i ] ;
1056
+ if ( replies ) {
1057
+ for ( i = 1 ; i < this . queue . length ; i += 1 ) {
1058
+ reply = replies [ i - 1 ] ;
1059
+ args = this . queue [ i ] ;
1058
1060
1059
- // If we asked for strings, even in detect_buffers mode, then return strings:
1060
- if ( self . _client . options . detect_buffers && to_buffer === false ) {
1061
- replies [ i - 1 ] = reply = reply_to_strings ( reply ) ;
1062
- }
1061
+ // If we asked for strings, even in detect_buffers mode, then return strings:
1062
+ if ( this . _client . options . detect_buffers && this . wants_buffers [ i ] === false ) {
1063
+ replies [ i - 1 ] = reply = reply_to_strings ( reply ) ;
1064
+ }
1063
1065
1064
- // TODO - confusing and error-prone that hgetall is special cased in two places
1065
- if ( reply && args [ 0 ] === "hgetall" ) {
1066
- replies [ i - 1 ] = reply = reply_to_object ( reply ) ;
1067
- }
1066
+ // TODO - confusing and error-prone that hgetall is special cased in two places
1067
+ if ( reply && args [ 0 ] === "hgetall" ) {
1068
+ replies [ i - 1 ] = reply = reply_to_object ( reply ) ;
1069
+ }
1068
1070
1069
- if ( typeof args [ args . length - 1 ] === "function" ) {
1070
- args [ args . length - 1 ] ( null , reply ) ;
1071
- }
1071
+ if ( typeof args [ args . length - 1 ] === "function" ) {
1072
+ args [ args . length - 1 ] ( null , reply ) ;
1072
1073
}
1073
1074
}
1075
+ }
1074
1076
1075
- if ( callback ) {
1076
- callback ( null , replies ) ;
1077
- } else if ( err && err . code !== 'CONNECTION_BROKEN' ) {
1078
- // Exclude CONNECTION_BROKEN so that error won't be emitted twice
1079
- self . _client . emit ( 'error' , err ) ;
1080
- }
1081
- } ) ;
1077
+ if ( this . callback ) {
1078
+ this . callback ( null , replies ) ;
1079
+ }
1082
1080
} ;
1083
1081
1084
1082
RedisClient . prototype . multi = RedisClient . prototype . MULTI = function ( args ) {
0 commit comments