dip*_*ipu 3 javascript promise
我会打一个电话到服务器以获得项目列表。如何确保只进行一次调用,并且仅处理一次集合以创建键值映射。
var itemMap = {};
function getItems(){
getAllItemsFromServer().then(function(data){
data.forEach(value){
itemMap[value.key] = value;
}});
return itemMap;
}
//need to get the values from various places, using a loop here
//to make multiple calls
var itemKeys = ['a', 'b', 'c'];
itemKeys.forEach(key){
var value = getItems().then(function(data){ return data[key]});
console.log('item for key=' + value);
}
Run Code Online (Sandbox Code Playgroud)
一个承诺是有状态的,一旦它被实现,它的值就不能改变。您可以.then多次使用来获取其内容,并且每次都会得到相同的结果。
该getAllItemsFromServer 函数返回一个承诺,then块操作响应并返回itemMap,它被包装在一个响应中(承诺链)。承诺然后被缓存,可用于itemMap 重复获取。
var itemsPromise = getItems(); // make the request once and get a promise
function getItems(){
return getAllItemsFromServer().then(function(data){
return data.reduce(function(itemMap, value){
itemMap[value.key] = value;
return itemMap;
}, {});
});
}
//need to get the values from various places, using a loop here
//to make multiple calls
var itemKeys = ['a', 'b', 'c'];
itemKeys.forEach(function(key){
itemsPromise.then(function(data){
return data[key];
}).then(function(value) {
console.log('item for key=' + value);
});
});
Run Code Online (Sandbox Code Playgroud)
我认为你真正想要的是
var cache = null; // cache for the promise
function getItems() {
return cache || (cache = getAllItemsFromServer().then(function(data){
var itemMap = {};
data.forEach(function(value){
itemMap[value.key] = value;
});
return itemMap;
}));
}
var itemKeys = ['a', 'b', 'c'];
itemKeys.forEach(function(key){
getItems().then(function(data){
return data[key];
}).then(function(value) {
console.log('item for key=' + value);
}); // notice that you get the value only asynchronously!
});
Run Code Online (Sandbox Code Playgroud)
我将添加一个用于缓存promise操作的通用方法。这里的窍门是,通过将promise作为值的真实代理并缓存它而不是值,我们避免了竞争条件。这同样适用于非承诺函数,说明了承诺如何很好地捕捉异步+值的概念。我认为这可以帮助您更好地理解问题:
function cache(fn){
var NO_RESULT = {}; // unique, would use Symbol if ES2015-able
var res = NO_RESULT;
return function () { // if ES2015, name the function the same as fn
if(res === NO_RESULT) return (res = fn.apply(this, arguments));
return res;
};
}
Run Code Online (Sandbox Code Playgroud)
这将使您可以非常轻松地缓存任何承诺(或非承诺操作):
var getItems = cache(getAllItemsFromServer);
getItems();
getItems();
getItems(); // only one call was made, can `then` to get data.
Run Code Online (Sandbox Code Playgroud)
请注意,您不能使其“同步”。
| 归档时间: |
|
| 查看次数: |
2841 次 |
| 最近记录: |