Javascript 如何通过映射的承诺传递数据?

Javascript 如何通过映射的承诺传递数据?,javascript,jquery,dictionary,nested,es6-promise,Javascript,Jquery,Dictionary,Nested,Es6 Promise,我有一个三阶段的mashup脚本,检查当地视频商店的最新租金,然后从烂西红柿(RT)中获得他们的批评百分比和同意: $(文档).ready(函数(){ $(“按钮”)。单击(函数(){ getNewRentals(url).然后(函数(ID){ var mapped=ids.map(函数(id,f){ 返回函数(){ 返回getRentalSpecs(id,f)。然后(函数(f,name,year){ return getroot(f,name,year);//只获取f! }); } }); v

我有一个三阶段的mashup脚本,检查当地视频商店的最新租金,然后从烂西红柿(RT)中获得他们的批评百分比和同意:

$(文档).ready(函数(){
$(“按钮”)。单击(函数(){
getNewRentals(url).然后(函数(ID){
var mapped=ids.map(函数(id,f){
返回函数(){
返回getRentalSpecs(id,f)。然后(函数(f,name,year){
return getroot(f,name,year);//只获取f!
});
}
});
var m=映射的[0]();
对于(变量i=1;i
一切都很好,只是最后一个函数getRotter只传递了f,而不是film name或year。映射循环一定有问题,因为所有三个函数都使用相同的jquery getJSON(通过Yahoo YQL)封装在标准js承诺中,该承诺同样解析代码中提到的参数。因此,如果数据从第一个函数传递到第二个函数,为什么不从第二个函数传递到第三个函数呢


我已经在这个回调/承诺的地狱里烤了几个星期了,现在已经很热了。这也是我第一次向SO发帖,所以请耐心听我说。

承诺表示一个值,它作为一个参数传递给任何
然后
处理程序。使用需要传递多个值的对象或数组(以更合适的为准):

您必须修改
getRentalSpecs
,以便它与属性为
f
名称和
年份的对象进行解析


我已将您的代码重构为使用
Promise.all()
,这使它更容易理解。似乎没有必要映射到函数表达式并按顺序手动调用其中的每一个表达式,因为它们彼此不依赖。

非常感谢@sdgluck!除了上面提到的,我刚刚将getRentalSpec更改为resolve({f,name,year}),现在它就像一个符咒一样工作!尽管object resolve看起来很熟悉,但我从未见过promise只代表一个值。您的回答非常迅速,以至于我完全没有编辑代码的复制/粘贴错误。因此,for循环中存在差异。噢,注释关闭得太快了!我的意思是,我将第二个函数的解析部分更改为
resolve({f,name,year})
@spo不客气。:-)我在我的回答中添加了一个ES6替代方案,它更加简洁,因为您可能正在使用一个transpiler。再次感谢您,@sdgluck。箭头函数对我来说是新的,乍一看是如此令人困惑,我需要先研究它。我没有使用transpiler,因此我的代码中可能存在的不一致之处来自于不断变化的应许之地:我刚刚跳过了这一潮流,我很难形成一个连贯的应许形象。jquery和vanilla js之间的差异也没有任何帮助。
$(document).ready(function(){
    $('button').click(function (){
        getNewRentals(url).then(function(ids){
            var mapped = ids.map(function(id, f){
                return function(){
                    return getRentalSpecs(id, f).then(function (f, name, year){
                        return getRotten(f, name, year); // Gets only f!
                    });
                }
            });
            var m = mapped[0]();
            for(var i = 1; i < mapped.length; i++) {
                m = m.then(mapped[i]);
            }
        });
    });
});
$(document).ready(function () {
    $('button').click(loadRotten);
});

function loadRotten () {
    return getNewRentals(url)
        .then(function (ids) {
            return Promise.all(ids.map(getRentalSpecs));
        })
        .then(function (objects) {
            return Promise.all(objects.map(function (obj) {
                return GetRotten(obj.f, obj.name, obj.year);
            });
            // Or refactor `GetRotten` to accept a single object
            // return Promise.all(objects.map(GetRotten));
        });
    });
}

// Or, using ES6, assuming refactor of `GetRotten`:

function loadRotten () {
    return getNewRentals(url)
        .then(ids => Promise.all(ids.map(getRentalSpecs)))
        .then(objects => Promise.all(objects.map(GetRotten));
}