【问题标题】:How to pass data through mapped promises?如何通过映射的 Promise 传递数据?
【发布时间】:2016-11-04 15:50:45
【问题描述】:

我有一个三阶段的 mashup 脚本,它检查本地音像店的最新租借内容,然后从烂番茄 (RT) 获得他们的评论百分比和共识:

$(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]);
            }
        });
    });
});

一切都很好,除了只有f被传递给最后一个函数getRotten,但没有 电影名字也没有年份。映射循环一定有问题,因为所有三个函数都使用相同的 jquery getJSON(通过 Yahoo YQL),它们同样包装在标准 js 承诺中,同样解析为代码中提到的参数。那么如果数据是从第一个函数传递到第二个,为什么不从第二个传递到第三个呢?

我已经在这个回调/承诺地狱中烤了几个星期了,现在我已经很生气了。这也是我在 SO 的第一篇文章,所以请多多包涵。

【问题讨论】:

    标签: javascript jquery dictionary nested es6-promise


    【解决方案1】:

    promise 表示单个值,它作为一个参数传递给任何then 处理程序。在需要传递多个值的地方使用对象或数组(以更合适的为准):

    $(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));
    }    
    

    您必须修改getRentalSpecs,以便它使用具有fnameyear 属性的对象进行解析。

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

    【讨论】:

    • 非常感谢@sdgluck!除了上述之外,我刚刚将 getRentalSpecs 更改为 resolve( { f, name, year } ) ,它现在就像一个魅力!尽管对象解析看起来很熟悉,但我从未见过承诺只代表一个值的文字。您的回答如此迅速,以至于我完全没有设法编辑我的代码的复制/粘贴错误。因此 for 循环中的差异。
    • 哦,cmets 关闭得太快了!我的意思是我将第二个函数的解析部分更改为resolve( { f, name, year } )
    • @spo 不客气。 :-) 我为我的答案添加了一个 ES6 替代方案,这更加简洁,因为也许您正在使用转译器。
    • 再次感谢您,@sdgluck。箭头函数对我来说是新的,第一眼看起来很莫名其妙,我需要先研究它。我没有使用转译器,所以我的代码中可能的不一致来自应许之地不断变化的景观:我刚刚赶上了潮流,我很难形成一个连贯的承诺形象。 jquery 和 vanilla js 之间的差异也没有任何帮助。
    猜你喜欢
    • 2018-10-12
    • 2019-05-10
    • 2021-09-30
    • 2011-12-07
    • 1970-01-01
    • 2018-10-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-17
    相关资源
    最近更新 更多