JS 回调函数可以 return 一个值吗?
Can JS callback functions ever return a value?
我完全理解为什么回调函数不能 return 一个值,如果回调内部的逻辑正在执行或在外部服务器上获取某些东西。
我不太明白的是,如果回调函数内的一切都正常,那么为什么回调函数不是 return 值,同步代码:
var myFunc = function(input, callback){
var sum = input + 10;
callback(sum);
};
sum = myFunc(1000, function(input){
console.log(input);
return input + 9000;
});
sum
仍然 return 未定义,即使 console.log
记录值 1010。
回调永远不能 return 是一条硬性规定吗?
而且其他语言的所有回调也从来没有 return 什么?
编辑
这是一个更复杂的例子 - 它也没有 return 任何东西
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);
您在 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;
});
需要特别说明的是,此示例中的回调没有什么特别之处。如果你链接函数,你只需要确保你 return
每个结果。我们可以将当前示例重写为:
function myInnerFunc(sum) {
return sum + 9000;
}
function myFunc (input){
var sum = input + 10;
return myInnerFunc(sum);
}
var sum = myFunc(1000);
但是,JavaScript 中 first-class 函数的性质允许我们传递函数。这在函数式编程中变得很有趣,现在可以将一个函数传递给各种其他函数以获得不同的结果。
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
异步操作会在稍后触发它们的回调,因此它们不能立即用于 return 值。最简单的示例是 setTimeout
,它会在 N
毫秒后调用其回调。在此示例中,myFunc
将在 setTimeout
有机会触发其回调之前很久就已被 returned。可以将相同的逻辑应用于 AJAX 回调。
function myFunc (value) {
var val;
window.setTimeout(function () {
val = value;
}, 1000)
return val;
}
var test = myFunc(1000)
console.log(test); // undefined
第 2 部分答案:电动舞曲
您还缺少 return
。
这一行
var result = checkDiscount(discountCode, orderFormContents, discounts);
分配 checkDiscount
的结果,但该函数没有 return 任何东西。
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
};
您可以通过 return 正确解决这个问题。
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;
});
}
}
};
老实说,这段代码真的很循环,很可能会被重构为更简洁的代码。
我完全理解为什么回调函数不能 return 一个值,如果回调内部的逻辑正在执行或在外部服务器上获取某些东西。
我不太明白的是,如果回调函数内的一切都正常,那么为什么回调函数不是 return 值,同步代码:
var myFunc = function(input, callback){
var sum = input + 10;
callback(sum);
};
sum = myFunc(1000, function(input){
console.log(input);
return input + 9000;
});
sum
仍然 return 未定义,即使 console.log
记录值 1010。
回调永远不能 return 是一条硬性规定吗?
而且其他语言的所有回调也从来没有 return 什么?
编辑
这是一个更复杂的例子 - 它也没有 return 任何东西
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);
您在 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;
});
需要特别说明的是,此示例中的回调没有什么特别之处。如果你链接函数,你只需要确保你 return
每个结果。我们可以将当前示例重写为:
function myInnerFunc(sum) {
return sum + 9000;
}
function myFunc (input){
var sum = input + 10;
return myInnerFunc(sum);
}
var sum = myFunc(1000);
但是,JavaScript 中 first-class 函数的性质允许我们传递函数。这在函数式编程中变得很有趣,现在可以将一个函数传递给各种其他函数以获得不同的结果。
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
异步操作会在稍后触发它们的回调,因此它们不能立即用于 return 值。最简单的示例是 setTimeout
,它会在 N
毫秒后调用其回调。在此示例中,myFunc
将在 setTimeout
有机会触发其回调之前很久就已被 returned。可以将相同的逻辑应用于 AJAX 回调。
function myFunc (value) {
var val;
window.setTimeout(function () {
val = value;
}, 1000)
return val;
}
var test = myFunc(1000)
console.log(test); // undefined
第 2 部分答案:电动舞曲
您还缺少 return
。
这一行
var result = checkDiscount(discountCode, orderFormContents, discounts);
分配 checkDiscount
的结果,但该函数没有 return 任何东西。
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
};
您可以通过 return 正确解决这个问题。
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;
});
}
}
};
老实说,这段代码真的很循环,很可能会被重构为更简洁的代码。