Как передавать информацию при работе с JavaScript Promise - PullRequest
0 голосов
/ 19 декабря 2018

В какой-то момент мы несколько раз вызываем наш бэкэнд с fetch.Каждый звонок возвращает обещание, которое мы собираем и передаем нашему responseHandler.Предполагается, что этот обработчик отправляет избыточные действия при поступлении каждого ответа. Действие будет изменяться по-разному в зависимости от двух факторов:

  • кода ответа сервера
  • содержимогозапрос

так что у нас есть

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.Поэтому я придумал следующий подход.Но он чувствует, что неправильно совмещать объект обещания.Я не могу сказать почему.

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

Как можно видеть, каждый раз, когда я хочу, чтобы значение области было доступно позже, я помещаю его в объект обещания, потому что этот объект обещания находится во всех других областях.Есть ли способ очистки ?

Примечание: серверная часть возвращает объект, который не обладает свойством _type (на самом деле я очищаю свои объекты от этих флагов перед отправкой их в серверную часть).Это флаг внешнего интерфейса, который мне все еще требуется, когда приходит ответ)

Ответы [ 3 ]

0 голосов
/ 19 декабря 2018

Обычным примером является использование одного глобального объекта (обычно называемого 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
    })
  })
})
0 голосов
/ 19 декабря 2018

Вы должны нести объект.Использование 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));
      });
  }
}

Обратите внимание, что вам вообще ничего не нужно делать со статусом, так как он все еще находился в области действия, где он используется.

0 голосов
/ 19 декабря 2018

Я бы попробовал что-то вроде следующего

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

, вы можете немного подправить, скажем, не пропуская весь объект, только поле типа.

...