JavaScript 初始化回调链中的回调参数

JavaScript initializing callback parameters down the callback chain

注意:我正在引导一个 reactjs 应用程序,但这是一个一般性的 JavaScript 问题。

我有一个特殊的模块 "locationUtils",我试图将其保留在它自己的包中,但将代码分开会导致回调令人讨厌。

当我访问其中一个方法时,我必须用它发送一个回调它只有一个最初定义的参数,在那个方法中我得到另一个数据参数初始化另一个参数。

我以后可以像 JavaScript 那样添加未定义的参数吗,像你一样为回调方法初始化参数是好习惯吗通常沿着回调链 走下去,还是我犯了一个令人费解的新手错误?

/********************Module 1******************************/
var bootStrapUI = function(callback) {
  locationUtils.findData(findOtherData(callback));
}

//This gets called last to finalize bootstraping
var findOtherData = function(callback,originalFetchedData){
 //use originalFetchedData to get more data
 //bootStraping program with all rendering data
 callback() //sends back a boolean confirming all fetched
}

/**********************Module2**********************************/

var findData = function(findOtherData){
  var data = magicGetData();
  findOtherData(findOtherData,data);//I initialized a param late here!
}

这是一个很好的 Javascript 问题,对于外行来说,回调可能会变成一个严重的地狱,特别是当它们被嵌套和/或它们 return 的顺序很重要时。

这就是 promises 的用武之地:它们是 Javascript 开发的重要工具,并且即将成为标准的一部分(在 EcmaScript 6 中)。

从本质上讲:promise 是一个对象,它是 return 从具有方法(回调)的函数编辑而来的,该方法在异步操作(例如 API 调用)完成时被调用。 promise 和回调之间的区别在于,promises 允许您构建处理回调的方式,重要的是,以什么顺序。

我最近编写了一个方法,该方法必须进行 30 次 api 调用,每次调用都取决于前一次调用的结果(这不是设计良好的 api)。您能想象尝试使用回调来做到这一点吗?事实上,我创建了一个承诺数组,并在所有 api 调用完成后使用 jQuery.when() 来处理事情。

目前我们需要使用 promises 库。 jQuery:https://api.jquery.com/jquery.deferred/ 是显而易见的,但还有许多其他实现可以做同样的事情。

更新:

这个问题更具体地涉及在回调之间传递参数以及在执行在它们之间移动时修改参数。这可以通过将您需要的任何信息作为参数传递给您的 resolve 方法来轻松完成。

通常看起来像这样(使用 jQuery):

var myAsyncMethod = function(info){

    var deferred = $.Deferred();

    $.getJSON(myUrl, 
        function(dataFromServer) {

            // Do stuff with data
            var newData = doSomething(dataFromServer);
            deferred.resolve(newData);

        });

    });

    return deferred.promise(); 

};

// Make initial method call
myAsyncMethod(myInitialData).then(
    function(transformedData){       
        // transformed data from server is returned here.
    }
);