如何在不使用参数的情况下创建javascript函数的实例

时间:2014-07-15 07:38:49

标签: javascript callback

我正在使用某些软件的JavaScript API。在软件中有解决方案,它们包含工作清单。

对于每个解决方案,我想列出工作清单。

solutions = obtainSolutionsformAPI();
for (i=0,i<solutions.length,i++){
    sol=solutions[i];
    sol.obtainWorklists(callbackFunction);    
}

callbackFunction由软件调用,工作列表数组作为参数传递。

function callbackFunction(arrayOfWorkLists){
    for (j=0,j<arrayOfWorkLists.length,j++){
        wl=arrayOfWorkLists[j];
        console.log(wl);
    }
}

现在在console.log中我想将每个工作清单中的i变量(解决方案的数量)打印出来,但是如何获取i内部回调函数,当我我不是那个叫它的人吗?我怀疑每次将其传递给sol.obtainWorklists(callbackFunction);之前我都需要修改回调函数。这样做的正确方法是什么?

编辑:我不希望函数定义嵌套(一个在其他内部),因为我有多个这样的嵌套,它将是非常难以理解的。所以我不想要这个:

sol.obtainWorklists(function callbackFunction(arrayOfWorkLists){...}); 

2 个答案:

答案 0 :(得分:2)

你需要使用一个闭包:

solutions = obtainSolutionsformAPI();
for (i=0,i<solutions.length,i++){
    (function(innerI) {
        sol=solutions[innerI];
        sol.obtainWorklists(function(worklists) {
            callbackFunction(worklists, innerI);
        }
    })(i);
}

function callbackFunction(arrayOfWorkLists, i){
    console.log(i);
    for (j=0,j<arrayOfWorkLists.length,j++){
        wl=arrayOfWorkLists[j];
        console.log(wl);
    }
}

答案 1 :(得分:2)

您可以使用构建器功能:

sol.obtainWorklists(buildCallback(i, callbackFunction));

... buildCallback看起来像这样:

function buildCallback(index, func) {
    return function() {
        var args = [index];
        args.push.apply(args, arguments);
        func.apply(this, args);
    };
}

完整示例

然后在你的回调中,期望i值作为第一个参数,其中obtainWorklists通常在其后面提供参数。

如何运作:

  • 当您致电 buildCallback时,您会传递i值和您想要的回叫。
  • buildCallback返回一个新函数,该函数绑定了该函数(它是对indexfunc参数的闭包 1}})。
  • buildCallback调用创建的函数obtainWorklists时,我们创建一个带有buildCallback值(i)的数组,后跟从{{1}收到的参数}。
  • 然后我们调用回调,使用与调用函数相同的index值和obtainWorklists数组;您的回调会将this中的条目视为离散参数。

如果您不关心回调中的args值,则可以改为使用ES5的args

this

这做了很多相同的事情,但不保留用于调用它的Function#bind


构建器函数的完整示例(live copy):

sol.obtainWorklists(callbackFunction.bind(null, i));

thislive copy)的完整示例:

// obtainWorklists stand-in
function obtainWorklists(func) {
    setTimeout(function() {
        // Just call it with a random number
        func(rand(100, 200));
    }, rand(100, 500));
}

// Code to get worklists
var i;
for (i = 0; i < 10; ++i) {
    obtainWorklists(buildCallback(i, callback));
}

function buildCallback(index, func) {
    return function() {
        var args = [index];
        args.push.apply(args, arguments);
        func.apply(this, args);
    };
}


// Your callback
function callback(index, value) {
    display("Index is " + index + ", value is " + value);
}

// ========= Utility functions
function rand(min, max) {
    return Math.floor(Math.random() * (max - min)) + min;
}
function display(msg) {
    var p = document.createElement('p');
    p.innerHTML = String(msg);
    document.body.appendChild(p);
}