打破链式功能

时间:2015-05-07 15:03:52

标签: javascript

我在一个对象上有一系列链接函数。例如:

var obj = {};
obj.a = function(){
    console.log('in a');  
    return this;
};


obj.b = function(){
    console.log('in b');  
    return this;
};

obj.c = function(){
    console.log('in c'); 
    return this;
};

obj.a().b().c();

显然,当我查看控制台时的结果是:

 in a
 in b
 in c

但是我如何突破这一点,以便ab执行但永远不会达到c

4 个答案:

答案 0 :(得分:2)

显而易见的答案是"只是不要拨打c",但我认为由于某种原因这不是一种选择。

除此之外,您可以通过在c之前从其中一个函数调用中抛出错误来解决它,但我不会推荐它。例外是错误处理,而不是流量控制[*]。

var obj = {};
obj.a = function(){
    console.log('in a');  
    return this;
};


obj.b = function(){
    console.log('in b');  
    if(shouldBreak) {
      throw new Error('decided to break');
    }

    return this;
};

obj.c = function(){
    console.log('in c'); 
    return this;
};

try {
  obj.a().b().c();
} catch {
  console.log('broke early')
}

[*] unless you're into Python

答案 1 :(得分:0)

只需在方法之外添加一个变量,比如说它叫做flag,默认为true。

将该标志设置为false后,您不希望继续使用的任何方法。然后在返回之前测试标志。

类似于:

var flag = true

function b() {
    flag = false
    return this
}

function c() {
    return flag ? this : null
}

答案 2 :(得分:0)

最简单的方法与打破任何函数调用的方式相同:抛出错误。

<?php

$mysqli  =  new mysqli("localhost","xampp","bt4521","BT Database");
/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

$sql = "LOAD DATA INFILE 'sfimport/sfdumptest.csv' INTO TABLE cases_cases
        FIELDS TERMINATED BY ','
        LINES TERMINATED BY '\\r\\n'
        IGNORE 1 LINES
        (name, @dummy, case_specific_notes, type, initiation_date, @dummy, @dummy)
";

//Try to execute query (not stmt) and catch mysqli error from engine and php error
if (!($stmt = $mysqli->query($sql))) {
    echo "\nQuery execute failed: ERRNO: (" . $mysqli->errno . ") " . $mysqli->error;
};
?>

然后调用方法并处理错误。

var obj = {
    someCondition: false,

    a: function() {
        return this;
    },

    b: function() {
        if (!this.someCondition) {
            var error = new Error("A message");
            error.name = "SomeConditionError";
            throw error;
        }

        return this;
    },

    c: function() {
        return this;
    }
};

您要避免的一件事是using exceptions for flow control

如果您需要拨打try { obj .a() .b() // throws a "SomeConditionError" here .c(); } catch (error) { if (error.name == "SomeConditionError") { // gracefully handle "SomeConditionError" } else { // rethrow errors you don't know how to handle gracefully throw error; } } 然后obj.a(),然后有条件地拨打obj.b(),那么主叫代码需要处理:

obj.c()

感觉就像丑陋的代码(并且它有点),但是这表明在这些方法调用中抛出的任何错误都是灾难性的,显示停止错误。如果您有一个涉及对一个对象或多个对象进行多个方法调用的复杂操作,请考虑将其封装在&#34; command&#34;中:

obj.a().b();

if (someCondition) {
    // Assign to "obj" just in case obj.c() returns a different object
    obj = obj.c();
}

从调用代码的角度来看,它只是简单地调用function DoSomethingCommand(obj) { this.obj = obj; } DoSomethingCommand.prototype = { constructor: DoSomethingCommand, execute: function() { this.obj.a().b(); if (someCondition) { this.obj = this.obj.c(); } } }; 来启动真正复杂的过程:

execute()

答案 3 :(得分:-1)

设置由a()检查的b()c()中的类字段。