使用 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());
});
这意味着我的问题来自更上游。该死的。
我有一组项目需要从数据库中删除。目前我的代码如下所示:
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());
});
这意味着我的问题来自更上游。该死的。