使用 reduce 串行链接 Javascript 承诺时的范围问题

Scope issue when chaining Javascript promises serially with reduce

我有一组项目需要从数据库中删除。目前我的代码如下所示:

getSomeItems.get()
    .then(function(result) {
        var actions = [];
        if (result.count) {
            result.data.forEach(function(item) {
                actions.push(function() {
                    console.log("Delete old item", item.id); 
                    return delAnItem(item.id); 
                });
            });
        }
        return actions.reduce(function(last, f) {
            return last.then(f);
        }, Q());
   });

给定以下数据:

{
    count: 3,
    data: [
        { id: 1 },
        { id: 2 },
        { id: 3 }
    ]
}

我想要输出:

Delete old item 1
Delete old item 2
Delete old item 3

我得到了输出(你可能已经猜到了):

Delete old item 3
Delete old item 3
Delete old item 3

我知道这是因为我的项目在更高的范围内(forEach),但我不知道如何修复它并将变量放入该本地范围。

除了你自己想出来的答案你还可以使用bind方法:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind

这是一个很常见的错误,很容易解决,而且出现了很多次。也简单干净:

result.data.forEach(function(item) {
    actions.push(function() {
         console.log("Delete old item", this.id); 
         return delAnItem(this.id); 
    }.bind(item));
});

Copied from the author's post:

经过一些反馈,这实际上运行良好。范围很好。这是一个完整的、可运行的测试:

var getSomeItems = function() {
    var deferred = Q.defer();
    deferred.resolve({ 
        count: 3, 
        data: [ 
            {id: 1}, 
            {id: 2}, 
            {id: 3}, 
        ]
    });
    return deferred.promise;
}

getSomeItems()
.then(function(result) {
    var actions = [];
    if (result.count) {
        result.data.forEach(function(item) {
            actions.push(
                (function() {
                    console.log("Delete old item", item.id); 
                })(item)
            );
        });
    }
    return actions.reduce(function(last, f) {
        return last.then(f);
    }, Q());
});

这意味着我的问题来自更上游。该死的。