【问题标题】:Problem with promises and asynchronous operations承诺和异步操作的问题
【发布时间】:2019-06-19 10:01:25
【问题描述】:

我必须向服务器发出 HTTP POST 请求,等待服务器响应,然后发出另一个请求(这会将服务器响应的一些数据发送回服务器)。我认为这是一项简单的任务,我做了这样的事情:

 const promise = new Promise((resolve, reject) => {
        resolve(this.updatePU(name, 'text', selectedOption.code));
      })
      promise.then(() => {
        console.log('Calling checkExpress function');
        let express = '';
        const puOrderNo = this.props.puOrderNo;
        fetch('/CheckExpress', {
          crossDomain: true,
          method: 'POST',
          headers: {
            'Accept': 'text/xml',
            'Content-Type': 'application/json',
          },
            body: JSON.stringify({"puOrderNo": puOrderNo })
        })
        .then(response => response.text())
        .then(str => {  
            express = convert.xml2json(str);
        }).then(() => {
            const data = JSON.parse(express);
            const checkExpress = data['elements'][0].elements[0].elements[0].elements[0].elements[0].text;
            console.log('checkExpress:', checkExpress);
            if(checkExpress === 'true'){
              this.props.updatePackageTypeField(true)
            } else {
              this.props.updatePackageTypeField(false);
            }
        })
        .catch(err => console.log(err));
      })

updatePU函数也是一个异步函数:

 updatePU = (name, type, value) => {
    const PUOrderNo = this.props.puOrderNo;
    const updatedValue = type === 'text' ? (`'${name}': '${value}'`) : (`'${name}': ${value}`);

    fetch('/ModifyPUOrder', {
      crossDomain: true,
      method: 'POST',
      headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json',
      },
        body: JSON.stringify({
          updatedValue: updatedValue,
          puOrderNo: PUOrderNo
        }),
    })
    .then(response => {
      if(response.ok){
        return response.json();
      } else {console.log(response)}
      throw new Error('Request failed!');
    }, networkError => {
      console.log(networkError.message);
    })
    .then(data => {
      if ("error" in data) {
        alert(data.error.message);
        this.refresh();
      }
      this.props.updatePUOrderForm(data);
    });
   }

结果是 promise 被忽略(我认为)并且第二个请求在第一个请求之前发出!我知道问题是在 promise 中解析的函数也是一个异步函数,但我不知道该怎么做。

任何帮助将不胜感激!

【问题讨论】:

    标签: javascript asynchronous redux promise


    【解决方案1】:

    主要问题是updatePU 没有返回承诺。你应该通过在fetch前面添加return来返回promise链的结果:

    return fetch('/ModifyPUOrder', {
    

    然后在顶部的代码中,不要创建新的承诺,使用来自updatePU 的承诺:

    this.updatePU(name, 'text', selectedOption.code)
    .then(() => {
        console.log('Calling checkExpress function');
        // ...
    

    还有第二个(基本上不相关的)问题:您正在将网络错误(拒绝)转换为履行:

    .then(response => {
      if(response.ok){
        return response.json();
      } else {console.log(response)}
      throw new Error('Request failed!');
    }, networkError => {                 // ***
      console.log(networkError.message); // *** Converts rejection to fulfillment with `undefined`
    })                                   // ***
    

    请记住,链中的每个处理程序都会转换通过它的内容。不抛出或返回拒绝的承诺的拒绝处理程序会将拒绝转换为履行。

    与其添加console.log 来到处转储错误,不如传播链,在无法进一步传播链的顶层,只需添加一个报告/处理错误的最终.catch(你的第一个代码块中确实有)。

    请参阅*** cmets 以获取有关这方面的说明以及其他一些内容:

    updatePU = (name, type, value) => {
        const PUOrderNo = this.props.puOrderNo;
        const updatedValue = type === 'text' ? (`'${name}': '${value}'`) : (`'${name}': ${value}`);
    
        return fetch('/ModifyPUOrder', {
          crossDomain: true,
          method: 'POST',
          headers: {
            'Accept': 'application/json',
            'Content-Type': 'application/json',
          },
            body: JSON.stringify({
              updatedValue: updatedValue,
              puOrderNo: PUOrderNo
            }),
        })
        .then(response => {
          if(response.ok){
            return response.json();
          } // *** No console.log here
          throw new Error('Request failed!'); // *** I wouldn't hide what happened, perhaps: `throw new Error("HTTP error " + response.status);`
        }/* ***No rejection handler here */)
        .then(data => {
          if ("error" in data) {
            alert(data.error.message);
            this.refresh();
            // *** You presumably want to return here or use `else` so you don't update the form below...?
          }
          this.props.updatePUOrderForm(data);
        });
    }
    

    【讨论】:

    • 先生。克劳德,我感激不尽。您不仅解决了我的问题,而且提出了一些非常好的观点(我担心错误处理)。我们需要更多像你这样的人,谢谢。
    • @Morgana - 你很友善!乐意效劳。 :-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-10-07
    • 1970-01-01
    • 1970-01-01
    • 2021-05-25
    • 1970-01-01
    • 2016-02-27
    • 1970-01-01
    相关资源
    最近更新 更多