我有一个请求承诺,我需要执行一个循环,如:
RealmMigration migration = new RealmMigration() {
@Override
public long execute(Realm realm, long version) {
Table table = realm.getTable(Dog.class);
table.convertColumnToNullable(table.getColumnIndex("name"));
return 1;
}
};
问题是我永远不知道数组中有多少元素,所以我需要一个动态模式。是否可以混合同步和异步世界,以便一时只有一个请求处于活动状态(序列不重要)?
答案 0 :(得分:11)
一种循环迭代数组的经典方法,在每个数组元素上调用一些异步操作是使用.reduce()
并链接到初始保证,如下所示:
问题是我永远不知道数组中有多少元素,所以 我需要一个动态模式。
您可以使用promises链接对其进行排序。为此,使用.reduce()
来迭代数组是很有用的,因为它提供了正确的迭代类型,可以在迭代数组时跟踪累积值(在这种情况下是一个promise)。您可以使用额外的变量使几乎任何数组迭代方案都工作,这与.reduce()
很好地对齐:
var ids = [1,2,3,4,5,6,7];
ids.reduce(function(p, item) {
return p.then(function() {
return doPromise(item);
});
}, Promise.resolve()).then(function(results) {
// all done here with array of results
});
这将一个已解决的承诺传递给ids.reduce()
作为承诺链的负责人。然后,它在该promise上执行.then()
并为数组中的每个项返回一个新的promise(通过.reduce()
回调)。 .reduce()
调用的最终结果将是一个承诺,当解决时意味着整个链完成。
理解这一点的关键是要记住p.then()
返回一个新的承诺,所以我们只是在每个新承诺上调用.then()
,并且我们从每个.then()
的每个操作中返回承诺处理程序。这具有将所有承诺链接在一起成为一个顺序链的效果。
是否可以混合同步和异步世界,以便只有一个 请求现在处于活动状态(序列不重要)?
我不确定你的意思是“混合同步和异步世界”。确保一次只有一个请求在飞行中的方法是将它们一个接一个地排序,以便下一个请求仅在前一个请求完成时开始。这也恰好保证了执行顺序,即使你说在这种情况下并不重要,但它是确保一次只有一个在飞行中的副产品。
而且,这是一个工作片段:
function log(msg) {
var d = document.createElement("div");
d.textContent = msg;
document.body.appendChild(d);
}
function doPromise(x) {
return new Promise(function(resolve) {
setTimeout(function() {
log(x);
resolve(x);
}, Math.floor(Math.random() * 1000));
});
}
var ids = [1,2,3,4,5,6,7];
ids.reduce(function(p, item) {
return p.then(function() {
return doPromise(item);
});
}, Promise.resolve()).then(function() {
// all done here
log("all done");
});