将额外的参数传递给返回回调

时间:2018-07-19 02:14:48

标签: javascript node.js

我正在使用以下格式的库函数:

let arr = [1,2,3]
arr.forEach((item, i) =>{
    doSomething(inputParam, (err, result)=>{
        ...
        //Use err and result
    });

})

errresult在我尚未开发的库函数中设置。

如何将额外的参数i传递给回调函数?

注意:我希望每个回调中的i对应于正确的索引。由于它们是异步的,所以在完成时它们都会看到i的最后一个值,这不是我想要的。例如,第二个回调应看到i = 2,第三个应看到i = 3。

我需要这样的东西:

let arr = [1,2,3]
arr.forEach((item, i) =>{
    doSomething(inputParam, (err, result, i)=>{
        ...
        //Use err and result
        console.log("i: ", i);
    });

})

2 个答案:

答案 0 :(得分:2)

您无法控制回调的参数。这些是由调用方设置的,调用方是doSomething()函数的内部函数,您说这不是您要控制的东西。因此,请勿尝试在其中添加呼叫者未设置的内容。那只会把你弄乱。

相反,由于您使用的是内联回调,因此您可以直接访问父作用域中的变量,而无需将其定义为回调的参数。这是Javascript的一个不错的功能(可访问父范围变量的内联回调)。

这是一个可运行的示例:

let arr = [1, 2, 3];
let inputParam = "something";

arr.forEach((item, i) => {
    doSomething(inputParam, (err, result) => {
        // you can access variables such as i in the parent scope here
        // from an inline callback

        //Use err and result
        console.log("i: ", i);
    });
});

function doSomething(param1, callback) {
    // simulate async callback
    setTimeout(function() {
        callback(null, "hello");
    }, 100);
}


如果您需要使用非内联的回调(例如在另一个模块中定义的回调),则可以创建一个小的内联回调存根,然后可以访问父范围的变量,然后可以使用所需的参数。

let arr = [1, 2, 3];
let inputParam = "something";

function yourExternalFunction(err, result, i) {
    // Use err and result and i
    console.log("i: ", i);
}

arr.forEach((item, i) => {
    doSomething(inputParam, (err, result) => {
        // you can access variables such as i in the parent scope here
        // from an inline callback
        yourExternalFunction(err, result, i) ;
    });
});

function doSomething(param1, callback) {
    // simulate async callback
    setTimeout(function() {
        callback(null, "hello");
    }, 100);
}

答案 1 :(得分:0)

您的第二次尝试即将结束,只需移除<!DOCTYPE html> <html> <head> <title>Hi</title> <link type="text/css" rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/chosen/1.8.7/chosen.css"> <style type="text/css"> table,td,th {margin-left: auto;margin-right: auto} .display {display: flex;align-items: center;justify-content: center;} p {text-align: center;} textarea {display: block;margin-left:auto;margin-right: auto;} .chosen-select {width:200px} </style> <script type="text/javascript" src="https://code.jquery.com/jquery-3.3.1.min.js"></script> <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/chosen/1.8.7/chosen.jquery.min.js"></script> <script type="text/javascript"> function sentence() { document.getElementById("s1").value = "";// reset document.getElementById("s1").style.display = "block"; document.getElementById("r1").style.display = "block"; if (document.getElementById("z1").value == "") { alert("Year, Make, and Model are needed"); document.getElementById("z1").focus(); } else { const input1 = document.getElementById("z1").value; var input3 = $('#z3').val(); console.log(input3); var input3Formatted = ""; if(input3.length==1){ // Only one value... input3Formatted = input3[0]; } if(input3.length==2){ // Two values... Just add and "and" input3Formatted = input3[0]+" and "+input3[1]; } if(input3.length>2){ // more than 2 values... for(i=0;i<input3.length-1;i++){ input3Formatted += input3[i]+", "; } input3Formatted += "and "+input3[input3.length-1]; } const input5 = "It has minor curb rash on the "+input3Formatted+"." const input7 = document.getElementById("z5").value; document.getElementById("s1").value = "This is my " +input1+ ". It is in good condition.The vehicle's rims have curb rash. "+input5+" The "+input1+"'s color is "+input7+"." } } function reset() { document.getElementById("s1").value = ""; } </script> <script type="text/javascript"> $(function() { $(".chosen-select").chosen({ disable_search_threshold: 4 }) }); </script> </head> <body> <table> <tr> <td> <input type="text" id="z1" placeholder="Year, Make, Model" name="name" maxlength="100" > </td> <td> <select data-placeholder="Minor Curb Rash" name="minorrash" multiple class="chosen-select" id="z3"> <option value=""></option> <option value="front left rim">Front Left Rim</option> <option value="back left rim">Back Left Rim</option> <option value="front right rim">Front Right Rim</option> <option value="back right rim">Back Right Rim</option> </select> </td> <td> <input type="text" id="z5" placeholder="Color" name="name" maxlength="100"> </td> </tr> </table> <br> <div class="display"> <button onclick="sentence()"> Submit </button> </div> <hr> <br> <textarea rows="10" cols="100" id="s1"></textarea> <br> <div class="display"> <button onclick="reset()" id="r1">Reset</button> </div> </body> </html>之后的i,它就会起作用

这里是JavaScript Scope

上的博客文章

result