ตอบสนอง redux - การใช้การดึงข้อมูลและการจัดส่งภายในการจัดส่งล้มเหลว

ฉันมีการดำเนินการที่จะบันทึกโทเค็น JWT ด้วยการเรียกง่ายๆว่า "saveJwt (data)"

นี่คือการดำเนินการ:

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
  }

จากนั้นฉันก็เพิ่มเข้าไปภายใต้ "saveJwt(data)" บล็อกโค้ดนี้:

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

สิ่งที่ต้องทำคือตรวจสอบว่ารายการอยู่ในที่จัดเก็บในตัวเครื่องหรือไม่ และหากเป็นเช่นนั้น ให้ทำการดึงข้อมูลอีกครั้งโดยเพิ่ม JWT

นี่คือการดำเนินการที่เสร็จสมบูรณ์เพื่อให้คุณเห็นว่ามันอยู่ที่ไหน:

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
  }

ดังนั้นตอนนี้การดึงข้อมูลครั้งแรกของฉันจบลงด้วยสัญญาที่ไม่ได้กำหนดไว้และมันก็กระโดดลงไปที่ด้านล่างโดยไม่ได้กำหนดมูลค่าของงาน

คุณจะเชื่อไหมว่าเมื่อวานมันทำงานได้อย่างสมบูรณ์แบบ และเมื่อฉันลองวันนี้มันก็ล้มเหลว

เหตุใดการบล็อกโค้ดนั้นทำให้ทุกอย่างล้มเหลว .. ฉันแสดงความคิดเห็นและมันก็ใช้ได้ดี ..

ฉันสงสัยว่ามันจะเกี่ยวข้องกับสัญญาสองข้อ ฯลฯ แต่จะต้องมีวิธีที่ถูกต้องในการจัดการสิ่งนี้ .. ฉันคิดว่าถ้ามันจะปิดลงเพื่อบันทึกโทเค็น JWT นั่นจะบ่งบอกว่ามันเสร็จสิ้นด้วยการดาวน์โหลดครั้งแรก แต่มีบางอย่าง อย่างอื่นผิด... ในบล็อกของโค้ดนั้นหรือมีแนวโน้มว่าจะมีการใช้อย่างไร


person si2030    schedule 03.05.2017    source แหล่งที่มา
comment
คุณหมายถึงสัญญา 'งาน' ส่งคืนบางสิ่งในกรณีแรกหรือส่งคืนค่าที่ไม่ได้กำหนดในวินาที (หลังการอัปเดต)? ฉันไม่แน่ใจว่าฉันเข้าใจปัญหาของคุณ แต่ฉันสงสัยว่าการส่งคืน geteSelectData จากฟังก์ชันที่เกี่ยวข้องอาจเป็นวิธีแก้ปัญหา   -  person Igor Popov    schedule 03.05.2017
comment
สงสัยว่าคุณจะขยายเรื่องนี้ออกไปถ้าคุณทำได้ .. @Igor   -  person si2030    schedule 03.05.2017
comment
ฉันไม่แน่ใจอีกครั้งว่าปัญหาคืออะไรสำหรับคุณ แต่โดยทั่วไปแล้วหากคุณคาดหวังว่าที่ใดที่ requestLoginToken จะแก้ไขได้หลังจาก วิธีการนำไปใช้ในขณะนี้ สัญญาว่าจะเรียกการดึงข้อมูลSelectData ดำเนินการในลักษณะที่คล้ายกับ 'ไฟแล้วลืม' และสิ่งเดียวที่ทำให้คุณรู้ว่ามันเสร็จสิ้นแล้วคือการกระทำ RECEIVE_SELECT_DATA   -  person Igor Popov    schedule 03.05.2017
comment
ConfirmSelectDataExistance() เป็นฟังก์ชัน async หรือไม่ หากส่งคืนสัญญา คุณจะต้องรอจนกว่าจะส่งคืนข้อมูล   -  person Dat Tran    schedule 03.05.2017
comment
@Igor ฉันเชื่อว่าคุณพูดถูกเกี่ยวกับเรื่องนี้ ... ConfirmSelectDataExistance() ไม่มีสัญญาที่แนบมาด้วย มันแค่ตรวจสอบว่ามีบางอย่างอยู่ใน localStorage หรือไม่ คุณจะเชื่อมโยงคำสั่งแบบมีเงื่อนไขและรันได้อย่างไรถ้ามันเป็นจริง?   -  person si2030    schedule 03.05.2017
comment
หากคุณคืนสัญญาจากฟังก์ชั่นมากกว่านั้นจะถูกล่ามโซ่ ฉันสงสัยว่า ConfirmSelectDataExistance ส่งคืนสัญญาด้วยตนเองหรือไม่ หากคุณเข้าใจผิดให้เรียกมันว่า ConfirmSelectDataExistance() กว่า (trueOrFalse =› {ถ้า (trueOrFalse) {ดึงข้อมูล}})   -  person Igor Popov    schedule 03.05.2017
comment
ขออภัย แต่ฉันมีปัญหากับวิธีเขียนไวยากรณ์นั้น .แล้ว(confirmSelectDataExistance()) =› ??   -  person si2030    schedule 03.05.2017
comment
ฉันจะโพสต์มันเป็นคำตอบ   -  person Igor Popov    schedule 03.05.2017


คำตอบ (1)


สมมติว่า ConfirmSelectDataExistance เป็นแบบอะซิงก์และส่งคืนสัญญาและสัญญาที่ดึงข้อมูลSelectData จะต้องได้รับการแก้ไขก่อนที่จะ requestLoginToken วิธีแก้ไขอาจเป็น:

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
}

หาก saveSelectData เป็นแบบอะซิงโครนัสด้วย คุณควรโทรแทน

 return saveSelectData(selectData);
person Igor Popov    schedule 03.05.2017