Javascript JS回调函数能返回值吗?

Javascript JS回调函数能返回值吗?,javascript,callback,Javascript,Callback,我完全理解,如果回调函数中的逻辑在外部服务器上执行或获取某些操作,为什么回调函数不能返回值 我不太明白的是,如果回调函数中的所有内容都是正常的同步代码,为什么回调函数不返回值: var myFunc = function(input, callback){ var sum = input + 10; callback(sum); }; sum = myFunc(1000, function(input){ console.log(input); return input + 9

我完全理解,如果回调函数中的逻辑在外部服务器上执行或获取某些操作,为什么回调函数不能返回值

我不太明白的是,如果回调函数中的所有内容都是正常的同步代码,为什么回调函数不返回值:

var myFunc = function(input, callback){
  var sum = input + 10;
  callback(sum);
};

sum = myFunc(1000, function(input){
  console.log(input);
  return input + 9000;
});
sum
仍然返回undefined,即使
console.log
记录的值为1010

回调永远不能返回任何东西,这是一条硬性规定吗

所有其他语言的回调也不会返回任何内容吗

编辑

这里有一个更复杂的示例,它也不会返回任何内容

discounts = [

  {
    sku: "126D",
    title: "Discount for using 126",
    discountCode: "LOVE126",
    discountAmount: -2500,
    check: function(orderFormContents, callback) {

      var discountsApplied = orderFormContents.discountsApplied;
      var sqft = orderFormContents.propertyInfo.sqft;

      for (var i = discountsApplied.length - 1; i >= 0; i--) {
        if (discountsApplied[i].discountCode === this.discountCode) {
          if (sqft < 1501) {
            return callback('', 'Coupon Added', this.discountAmount);
          } else {
            return callback('', 'Coupon Added', (this.discountAmount + -2500));
          };
        };
      };

    }
  },

  // additional discount objects in array


];

var checkDiscount = function(code, orderFormContents, allDiscounts) {
  for (var i = allDiscounts.length - 1; i >= 0; i--) {
    if (allDiscounts[i].discountCode === code) {
      allDiscounts[i].check(orderFormContents, function(error, message, amount) {
          var result = {
            "error": error,
            "message": message,
            "amount": amount
          };
          debugger
          return result;
      });
    };
  };
};

var orderFormContents = {
  propertyInfo: {
    sqft: 1000
  },
  discountsApplied: [
    {
      discountCode: "LOVE126"
    }
  ]
};

var discountCode = "LOVE126";

var result = checkDiscount(discountCode, orderFormContents, discounts);
debugger
console.log(result);
折扣=[
{
sku:“126D”,
标题:“使用126折扣”,
折扣代码:“LOVE126”,
折扣额:-2500,
检查:函数(orderFormContents,回调){
var折扣已应用=orderFormContents.discountsApplied;
var sqft=orderFormContents.propertyInfo.sqft;
对于(var i=discountsApplied.length-1;i>=0;i--){
如果(折扣已应用[i]。折扣代码===此。折扣代码){
如果(平方英尺<1501){
返回回拨(''‘已添加优惠券',此为折扣金额);
}否则{
返回回调(“”,'添加优惠券',(this.discountAmount+-2500));
};
};
};
}
},
//数组中的其他折扣对象
];
var checkDiscount=函数(代码、orderFormContents、allDiscounts){
对于(var i=alldiscounters.length-1;i>=0;i--){
if(所有折扣[i]。折扣代码===代码){
所有折扣[i]。检查(orderFormContents,函数(错误,消息,金额){
var结果={
“错误”:错误,
“信息”:信息,
“金额”:金额
};
调试器
返回结果;
});
};
};
};
var orderFormContents={
propertyInfo:{
平方英尺:1000
},
折扣包括:[
{
折扣代码:“LOVE126”
}
]
};
var折扣代码=“LOVE126”;
var结果=检查折扣(折扣代码、订单内容、折扣);
调试器
控制台日志(结果);

您在
myFunc
中缺少return语句

var myFunc = function(input, callback){
  var sum = input + 10;
  return callback(sum);
};

sum = myFunc(1000, function(input){
  console.log(input);
  return input + 9000;
});
为了进一步澄清,本例中的回调没有什么特别之处。如果要链接函数,只需确保
返回每个结果。我们可以将当前示例改写为:

function myInnerFunc(sum) {
  return sum + 9000;
}

function myFunc (input){
  var sum = input + 10;
  return myInnerFunc(sum);
}

var sum = myFunc(1000);
但是,JavaScript中一流函数的性质允许我们传递函数。这在函数式编程中变得很有趣,其中一个函数现在可以传递给不同的其他函数以获得不同的结果

function add (a, b) {
  return a + b;
}

function multi (a, b) {
  return a * b;
}

var list = [1, 2, 3, 4, 5];

console.log(list.reduce(add)); // 15
console.log(list.reduce(multi)); // 120
异步操作会在稍后的某个时间触发回调,因此不能立即使用它们返回值。最简单的例子是
setTimeout
,它在
N
毫秒后调用其回调。在本例中,
myFunc
将在
setTimeout
有机会触发回调之前很久返回。同样的逻辑也可以应用于AJAX回调

function myFunc (value) {
  var val;
  window.setTimeout(function () {
    val = value;
  }, 1000)
  return val;
}

var test = myFunc(1000)

console.log(test); // undefined

回答第2部分:电动Boogaloo 您仍然缺少一个
返回值

这条线

var result = checkDiscount(discountCode, orderFormContents, discounts);
checkDiscount
分配结果,但该函数不返回任何内容

var checkDiscount = function(code, orderFormContents, allDiscounts) {
  for (var i = allDiscounts.length - 1; i >= 0; i--) {
    if (allDiscounts[i].discountCode === code) {
      allDiscounts[i].check(orderFormContents, function(error, message, amount) {
        var result = {
          "error": error,
          "message": message,
          "amount": amount
        };
        return result;
      });
    }
  }
  // Never returned, default return value is undefined
};
您可以通过正确返回来修复此问题

var checkDiscount = function(code, orderFormContents, allDiscounts) {
  for (var i = allDiscounts.length - 1; i >= 0; i--) {
    if (allDiscounts[i].discountCode === code) {
      return allDiscounts[i].check(orderFormContents, function(error, message, amount) {
        var result = {
          "error": error,
          "message": message,
          "amount": amount
        };
        return result;
      });
    }
  }
};

老实说,这段代码真的很简单,很可能会被重构成更简洁的代码。

您在
myFunc
中缺少了return语句

var myFunc = function(input, callback){
  var sum = input + 10;
  return callback(sum);
};

sum = myFunc(1000, function(input){
  console.log(input);
  return input + 9000;
});
为了进一步澄清,本例中的回调没有什么特别之处。如果要链接函数,只需确保
返回每个结果。我们可以将当前示例改写为:

function myInnerFunc(sum) {
  return sum + 9000;
}

function myFunc (input){
  var sum = input + 10;
  return myInnerFunc(sum);
}

var sum = myFunc(1000);
但是,JavaScript中一流函数的性质允许我们传递函数。这在函数式编程中变得很有趣,其中一个函数现在可以传递给不同的其他函数以获得不同的结果

function add (a, b) {
  return a + b;
}

function multi (a, b) {
  return a * b;
}

var list = [1, 2, 3, 4, 5];

console.log(list.reduce(add)); // 15
console.log(list.reduce(multi)); // 120
异步操作会在稍后的某个时间触发回调,因此不能立即使用它们返回值。最简单的例子是
setTimeout
,它在
N
毫秒后调用其回调。在本例中,
myFunc
将在
setTimeout
有机会触发回调之前很久返回。同样的逻辑也可以应用于AJAX回调

function myFunc (value) {
  var val;
  window.setTimeout(function () {
    val = value;
  }, 1000)
  return val;
}

var test = myFunc(1000)

console.log(test); // undefined

回答第2部分:电动Boogaloo 您仍然缺少一个
返回值

这条线

var result = checkDiscount(discountCode, orderFormContents, discounts);
checkDiscount
分配结果,但该函数不返回任何内容

var checkDiscount = function(code, orderFormContents, allDiscounts) {
  for (var i = allDiscounts.length - 1; i >= 0; i--) {
    if (allDiscounts[i].discountCode === code) {
      allDiscounts[i].check(orderFormContents, function(error, message, amount) {
        var result = {
          "error": error,
          "message": message,
          "amount": amount
        };
        return result;
      });
    }
  }
  // Never returned, default return value is undefined
};
您可以通过正确返回来修复此问题

var checkDiscount = function(code, orderFormContents, allDiscounts) {
  for (var i = allDiscounts.length - 1; i >= 0; i--) {
    if (allDiscounts[i].discountCode === code) {
      return allDiscounts[i].check(orderFormContents, function(error, message, amount) {
        var result = {
          "error": error,
          "message": message,
          "amount": amount
        };
        return result;
      });
    }
  }
};

老实说,这段代码确实是looptastic,很可能会被重构成更简洁的代码。

@JasonWilczak关于这段代码示例的任何内容都不是异步的。通常,使用回调的东西甚至不需要检查返回。从理论上讲,这是可能的,但我从未见过任何库或真正的代码利用它,比如记录“退出代码”或something@Oka感谢您注意:)我完全误读了这个问题并删除了我的注释。@JasonWilczak关于这个代码示例的任何内容都不是异步的。通常,使用回调的东西甚至不需要检查返回。从理论上讲,这是可能的,但我从未见过任何库或真正的代码利用它,比如记录“退出代码”或something@Oka谢谢注意:)我完全误解了这个问题,删除了我的评论。嗯。。。有趣。我想这部分让我有点困惑。当我执行
返回回调(sum)
时,它基本上是这样做的:
返回函数(input){console.log(input);return input+9000;}
哦,现在它完全有意义了。基本上,运行函数返回一个值,但是您需要立即返回该值。但是,如果回调中的逻辑实际上是异步的,那么这将不起作用,对吗?是的,asyn