欢迎来到 promise(d) hell ;-)
Welcome to promise(d) hell ;-)
我想使用 promises 异步加载一些文件并编写了这个解决方案:
function create(ids, $q, http) {
var promises = [];
_.each(ids, function(id) {
var item = http.get('catalog/' + id + '.json').then(function (response) {
return {id: id, item: response.data};
}, function(reason) {
console.log(reason.config.url, reason.statusText, reason.status);
});
promises.push(item);
});
return $q.all(promises).then(function(values) {
var catalog = {};
var svgPromises = [];
_.each(values, function(value) {
catalog[value.id] = value.item;
var svg = http.get('catalog/' + value.item.svg).then(function (response) {
return {id: value.id, svg: response.data};
}, function(reason) {
console.log(reason.config.url, reason.statusText, reason.status);
});
svgPromises.push(svg);
});
return $q.all(svgPromises).then(function(values) {
_.each(values, function(value) {
catalog[value.id].svg = value.svg;
});
return catalog;
});
});
}
我不太喜欢它,我知道我可以使用地图让它变得更好一点,但我不相信我做对了。有人知道怎么做更好吗?
创建第三个延迟对象怎么样,然后我们只在所有调用完成后才解析延迟对象? (由于我无法测试,下面的代码可能有一些错误,但希望思路清晰)
function create(ids, $q, http) {
var promises = [];
var catalog = {};
_.each(ids, function (id) {
var svgDef = $q.defer();
http.get('catalog/' + id + '.json')
.then(
function (response) {
var value = {id: id, item: response.data};
catalog[value.id] = value.item;
http.get('catalog/' + value.item.svg)
.then(
function (response) {
catalog[value.id].svg = response.data;
svgDef.resolve(catalog[value.id]);
},
function (reason) {
console.log(reason.config.url, reason.statusText, reason.status);
svgDef.reject(reason);
});
},
function (reason) {
console.log(reason.config.url, reason.statusText, reason.status);
svgDef.reject(reason);
});
promises.push(svgDef.promise);
});
return $q.all(promises)
.then(function () {
return catalog;
})
}
function create(ids, $q, http) {
var catalog = {};
return $q.all(_.map(ids, function(id) {
return http.get('catalog/' + id + '.json')
.then(function(response) {
catalog[id] = {id: id, item: response.data};
return http.get('catalog/' + response.data.svg);
})
.then(function(response) {
catalog[id].svg = response.data;
})
.catch(function(e) {
console.log(e.config.url, e.statusText, e.status);
});
})).then(function() {
return catalog;
});
}
我想使用 promises 异步加载一些文件并编写了这个解决方案:
function create(ids, $q, http) {
var promises = [];
_.each(ids, function(id) {
var item = http.get('catalog/' + id + '.json').then(function (response) {
return {id: id, item: response.data};
}, function(reason) {
console.log(reason.config.url, reason.statusText, reason.status);
});
promises.push(item);
});
return $q.all(promises).then(function(values) {
var catalog = {};
var svgPromises = [];
_.each(values, function(value) {
catalog[value.id] = value.item;
var svg = http.get('catalog/' + value.item.svg).then(function (response) {
return {id: value.id, svg: response.data};
}, function(reason) {
console.log(reason.config.url, reason.statusText, reason.status);
});
svgPromises.push(svg);
});
return $q.all(svgPromises).then(function(values) {
_.each(values, function(value) {
catalog[value.id].svg = value.svg;
});
return catalog;
});
});
}
我不太喜欢它,我知道我可以使用地图让它变得更好一点,但我不相信我做对了。有人知道怎么做更好吗?
创建第三个延迟对象怎么样,然后我们只在所有调用完成后才解析延迟对象? (由于我无法测试,下面的代码可能有一些错误,但希望思路清晰)
function create(ids, $q, http) {
var promises = [];
var catalog = {};
_.each(ids, function (id) {
var svgDef = $q.defer();
http.get('catalog/' + id + '.json')
.then(
function (response) {
var value = {id: id, item: response.data};
catalog[value.id] = value.item;
http.get('catalog/' + value.item.svg)
.then(
function (response) {
catalog[value.id].svg = response.data;
svgDef.resolve(catalog[value.id]);
},
function (reason) {
console.log(reason.config.url, reason.statusText, reason.status);
svgDef.reject(reason);
});
},
function (reason) {
console.log(reason.config.url, reason.statusText, reason.status);
svgDef.reject(reason);
});
promises.push(svgDef.promise);
});
return $q.all(promises)
.then(function () {
return catalog;
})
}
function create(ids, $q, http) {
var catalog = {};
return $q.all(_.map(ids, function(id) {
return http.get('catalog/' + id + '.json')
.then(function(response) {
catalog[id] = {id: id, item: response.data};
return http.get('catalog/' + response.data.svg);
})
.then(function(response) {
catalog[id].svg = response.data;
})
.catch(function(e) {
console.log(e.config.url, e.statusText, e.status);
});
})).then(function() {
return catalog;
});
}