使用JavaScript Promise时如何传递信息

时间:2018-12-19 15:07:42

标签: javascript promise es6-promise

有一次,我们使用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属性的对象(实际上,我在将这些标志发送给后端之前先清除了这些标志的对象。这是当答案到来时仍需要的一个前端标志)

3 个答案:

答案 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)

常见的模式是使用单个全局对象(通常称为stateappData或类似名称)存储值,并允许您从不同的闭包内部访问它们。

这是一个使用此模式来加载一堆项目,然后在单击“刷新”按钮后重新加载每个项目的数据的人为示例:

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
    })
  })
})