react redux - menerapkan pengambilan dan pengiriman di dalam pengiriman gagal

Saya memiliki tindakan kerja yang menyimpan token JWT dengan panggilan sederhana "saveJwt(data)".

Inilah aksinya:

export const requestLoginToken = (username, password) =>
  (dispatch, getState) => {
    dispatch({type: REQUEST_LOGIN_TOKEN, payload: username})

    const payload = {
      userName: username,
      password: password,
    }

    const task = fetch('/api/jwt', {
      method: 'POST',
      body: JSON.stringify(payload),
      headers: {
        'Content-Type': 'application/json;charset=UTF-8'
      },
    })
      .then(handleErrors)
      .then(response => response.json())
      .then(data => {
        dispatch({type: RECEIVE_LOGIN_TOKEN, payload: data})
        saveJwt(data)
      })
      .catch(error => {
        clearJwt()
        dispatch({type: ERROR_LOGIN_TOKEN, payload: error.message})
      })
    addTask(task)
    return task
  }

Saya kemudian menambahkan tepat di bawah "saveJwt(data)" Blok kode ini:

    if (!confirmSelectDataExistance()) {
      dispatch({ type: REQUEST_SELECT_DATA })
      const token = getJwt()
      const headers = new Headers({
        'Authorization': `Bearer ${token}`
      })
      const retrieveSelectData = fetch('/api/SelectData/SelectData', {
        method: 'GET',
        headers: {
          'Content-Type': 'application/json;charset=UTF-8'
        },
      })
        .then(handleErrors)
        .then(response => response.json())
        .then(selectData => {
          dispatch({ type: RECEIVE_SELECT_DATA, payload: selectData })
          saveSelectData(selectData)
        })
   }

Yang harus dilakukan hanyalah memeriksa apakah item ada di penyimpanan lokal dan jika demikian, lakukan pengambilan lagi kali ini dengan JWT ditambahkan.

Berikut adalah tindakan yang telah selesai sehingga Anda dapat melihat posisinya:

export const requestLoginToken = (username, password) =>
  (dispatch, getState) => {
    dispatch({ type: REQUEST_LOGIN_TOKEN, payload: username })

    const payload = {
      userName: username,
      password: password,
    }

    const task = fetch('/api/jwt', {
      method: 'POST',
      body: JSON.stringify(payload),
      headers: {
        'Content-Type': 'application/json;charset=UTF-8'
      },
    })
      .then(handleErrors)
      .then(response => response.json())
      .then(data => {
        dispatch({ type: RECEIVE_LOGIN_TOKEN, payload: data })
        saveJwt(data)
        //selectData download if nothing is local storage.
        if (!confirmSelectDataExistance()) {
          dispatch({ type: REQUEST_SELECT_DATA })
          const token = getJwt()
          const headers = new Headers({
            'Authorization': `Bearer ${token}`
          })
          const retrieveSelectData = fetch('/api/SelectData/SelectData', {
            method: 'GET',
            headers: {
              'Content-Type': 'application/json;charset=UTF-8'
            },
          })
            .then(handleErrors)
            .then(response => response.json())
            .then(selectData => {
              dispatch({ type: RECEIVE_SELECT_DATA, payload: selectData })
              saveSelectData(selectData)
            })
        }
      })
      .catch(error => {
        clearJwt()
        dispatch({ type: ERROR_LOGIN_TOKEN, payload: error.message })
      })
    addTask(task)
    return task
  }

Jadi sekarang pengambilan pertama saya berakhir dengan janji yang tidak ditentukan dan langsung turun ke bawah dengan nilai tugas yang tidak ditentukan,,

Percayakah Anda kemarin itu berfungsi dengan sempurna dan ketika saya mencobanya hari ini gagal.

Mengapa blok kode itu menyebabkan semuanya gagal.. Saya mengomentarinya dan berfungsi dengan baik..

Saya curiga ini ada hubungannya dengan dua janji dll tetapi harus ada cara yang benar untuk mengelola ini.. Saya akan berpikir bahwa jika itu akan menyimpan token JWT itu akan menunjukkan selesai dengan unduhan pertama namun ada sesuatu yang lain salah... dalam blok kode itu atau lebih mungkin cara penggunaannya.


person si2030    schedule 03.05.2017    source sumber
comment
Apakah maksud Anda janji 'tugas' mengembalikan sesuatu dalam kasus pertama atau mengembalikan nilai yang tidak ditentukan dalam kasus kedua (setelah pembaruan)? Saya tidak yakin saya memahami masalah Anda, tetapi saya menduga mengembalikan retrieveSelectData dari fungsi terkait mungkin bisa menjadi solusi   -  person Igor Popov    schedule 03.05.2017
comment
Ingin tahu apakah Anda dapat memperluas ini jika Anda bisa.. @Igor   -  person si2030    schedule 03.05.2017
comment
Sekali lagi, saya tidak yakin apa masalahnya bagi Anda, tetapi secara umum jika Anda mengharapkan penyelesaian requestLoginToken setelah retrieveSelectData menyelesaikannya, maka diperlukan rangkaian yang lebih baru ke yang sebelumnya. Cara penerapannya sekarang janji retrieveSelectData dijalankan dengan cara yang mirip dengan 'api dan lupakan' dan satu-satunya hal yang membuat Anda sadar akan penyelesaiannya adalah tindakan RECEIVE_SELECT_DATA   -  person Igor Popov    schedule 03.05.2017
comment
apakah konfirmasiSelectDataExistance() merupakan fungsi async? Jika ia mengembalikan janji, maka Anda harus menunggu hingga ia mengembalikan data.   -  person Dat Tran    schedule 03.05.2017
comment
@Igor Saya yakin Anda benar tentang ini... konfirmasiSelectDataExistance() tidak memiliki janji. itu hanya memeriksa apakah ada sesuatu di Penyimpanan lokal. Bagaimana Anda merangkai pernyataan bersyarat dan menjalankannya jika pernyataan itu benar?   -  person si2030    schedule 03.05.2017
comment
Jika Anda mengembalikan janji dari fungsi maka janji itu akan dirantai. Saya ingin tahu apakah konfirmasiSelectDataExistance mengembalikan janji sendiri. Jika Anda salah, sebut saja seperti konfirmasiSelectDataExistance(). daripada(trueOrFalse =› {if (trueOrFalse) {ambil}})   -  person Igor Popov    schedule 03.05.2017
comment
Maaf tapi saya mengalami masalah dengan cara menulis sintaksis itu. .lalu(konfirmasiSelectDataExistance()) =› ??   -  person si2030    schedule 03.05.2017
comment
Saya akan mempostingnya sebagai jawaban   -  person Igor Popov    schedule 03.05.2017


Jawaban (1)


Dengan asumsi bahwa konfirmasiSelectDataExistance adalah async dan mengembalikan janji dan janji tersebut retrieveSelectData harus diselesaikan sebelum requestLoginToken solusinya mungkin:

export const requestLoginToken = (username, password) =>
(dispatch, getState) => {
   dispatch({ type: REQUEST_LOGIN_TOKEN, payload: username })

   const payload = {
     userName: username,
     password: password,
   }

const task = fetch('/api/jwt', {
  method: 'POST',
  body: JSON.stringify(payload),
  headers: {
    'Content-Type': 'application/json;charset=UTF-8'
  },
})
  .then(handleErrors)
  .then(response => response.json())
  .then(data => {
    dispatch({ type: RECEIVE_LOGIN_TOKEN, payload: data })
    saveJwt(data)
    //selectData download if nothing is local storage.

    return confirmSelectDataExistance().then(isConfirmed => {
      if (!isConfirmed) {
        dispatch({ type: REQUEST_SELECT_DATA })
        const token = getJwt()
        const headers = new Headers({
          'Authorization': `Bearer ${token}`
        })
        const retrieveSelectData = fetch('/api/SelectData/SelectData', {
          method: 'GET',
          headers: {
            'Content-Type': 'application/json;charset=UTF-8'
          },
        })
        .then(handleErrors)
        .then(response => response.json())
        .then(selectData => {
          dispatch({ type: RECEIVE_SELECT_DATA, payload: selectData })
          saveSelectData(selectData)
        });

        return retrieveSelectData;
      }
    })
  })
  .catch(error => {
    clearJwt()
    dispatch({ type: ERROR_LOGIN_TOKEN, payload: error.message })
  })
addTask(task)
return task
}

Jika saveSelectData juga async, Anda harus meneleponnya

 return saveSelectData(selectData);
person Igor Popov    schedule 03.05.2017