有一次,我们使用fetch
多次调用我们的后端。每个调用都返回一个承诺,我们将收集并传递给我们的responseHandler
。该处理程序应该在每个响应进入时调度redux动作。该动作的形状将基于两个因素而有所不同:
所以我们有这个
function save(objects) {
let promises = objects.map(object => {
let promise = fetch(url, {..., body: object});
});
responseHandler(promises);
}
function responseHandler(promises) {
for (let promise of promises) {
promise
.then(r => {
return r.json();
})
.then(body => dispatchSomeAction(body));
}
}
到目前为止,一切都很好。但是现在,我们需要save
内部以及接收response
对象的匿名函数内部的信息。所以我想出了以下方法。但是,piggy带在promise对象上感觉错误。我不能说为什么。
function save(objects) {
let promises = objects.map(object => {
let promise = fetch(url, {..., body: object});
promise._objectType = object._type;
});
responseHandler(promises);
}
function responseHandler(promises) {
for (let promise of promises) {
promise
.then(r => {
promise._status = r.status;
return r.json();
})
.then(body => dispatchSomeAction({
status: promise._status,
type: promise._type, ...body
}));
}
}
可以看出,每次我希望以后可以使用范围的值时,我都会将其放在promise对象上,因为该promise对象位于所有其他范围中。有更清洁的方法吗?
注意:后端返回一个不具有_type
属性的对象(实际上,我在将这些标志发送给后端之前先清除了这些标志的对象。这是当答案到来时仍需要的一个前端标志)
答案 0 :(得分:1)
您必须携带物品。使用ES6进行结构化和解构不是很笨拙:
function save(objects){
let promises = objects.map(object => {
return fetch(url, {..., body: object}).then(r => ({r,type:object._type}));
}
responseHandler(promises)
}
function responseHandler(promises){
for (let promise of promises){
promise
.then(({r,type}) => {
return r.json().then(body => dispatchSomeAction({status: r.status, type, ...body));
});
}
}
请注意,您实际上不需要对状态进行任何操作,因为它仍然在使用状态范围内。
答案 1 :(得分:0)
我会尝试以下类似的方法
function save(objects){
let promises = objects.map(object) =>{
return fetch(url, {..., body: object}).then(r=>{
return {data: r, originalObject: object}
})
}
responseHandler(promises)
}
function responseHandler(promises){
for (let promise of promises){
promise
.then(r => {
return {data: r.data.json(), originalObject: r.originalObject)
.then(r=> dispatchSomeAction({status: r.data.status, type: r.originalObject.type, ...r.data.body));
}
}
您可以进行一些调整,例如,不传递整个对象,而只需传递类型字段即可。
答案 2 :(得分:0)
常见的模式是使用单个全局对象(通常称为state
或appData
或类似名称)存储值,并允许您从不同的闭包内部访问它们。
这是一个使用此模式来加载一堆项目,然后在单击“刷新”按钮后重新加载每个项目的数据的人为示例:
const state = {}
getItemsPromise().then(response => {
state.items = response.items
})
$(refreshItemsButton).on('click', ()=>{
state.items.forEach(item => {
refreshItemPromise(item).then(response => {
state.items[item.id] == response.item
})
})
})