【问题标题】:Processing replies from the javascript Fetch API处理来自 javascript Fetch API 的回复
【发布时间】:2018-02-25 09:55:50
【问题描述】:

我正在努力处理我的 fetch() POST 请求。它运行成功,我可以很好地看到数据并使用它——但只能在 fetch() 调用中。我想将数据传回 App.js(我将我的 fetch() API 保存在它自己的实用程序模块 .js 文件中)......但时间已经过去了。根据控制台日志调试,看起来包含 fetch 的函数在 fetch 完全解析之前返回到原始调用。

这些是控制台结果。成功/文本对象是我从包含我的 fetch() 的 N4RecordScan.submit() 函数返回的。然后几行之后,我们看到了 Promise 的解决。所以我的 App.js 没有数据。

我将不胜感激任何指导!我觉得我很接近了!

{success: "", text: ""}  
Processing final response.  
Fetch finished loading: OPTIONS 
{argo:gateresponse: {…}, status: "0", statusid: "OK"}

这是来自我的 App.JS 的 sn-p,它调用并进一步处理 fetch 函数。

  processResponse(myResponseObject) {
    this.setState({
      responseAlerts: this.state.responseAlerts.push(myResponseObject)
    });
    console.log('Processing final response. '+ myResponseObject.success + ' ' + myResponseObject.text);
  }

  sendRequest() {
    let response = N4RecordScan.submit(this.interpolateRequest(), this.state.server, this.state.endpoint);
    this.processResponse(response);
  }

这是我的 fetch() 所在的函数:

export const N4RecordScan = {

    submit(data, server, endpoint) {
        let headers = new Headers();
        let success = '';
        let text = '';

        headers.append('Content-Type', 'text/xml');
        headers.append('SOAPAction', 'basicInvoke');
        headers.append('Authorization', 'Basic ' + base64.encode(username + ":" + password));

        let dataPrefix = '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:arg="http://www.navis.com/services/argobasicservice"><soapenv:Header/><soapenv:Body><arg:basicInvoke><arg:scopeCoordinateIds>APMT/USLAX/LAX/LAX</arg:scopeCoordinateIds><arg:xmlDoc><![CDATA[';
        let dataSuffix = ']]></arg:xmlDoc></arg:basicInvoke></soapenv:Body></soapenv:Envelope>';

        data = dataPrefix + data + dataSuffix;

        console.log('about to send ' + data);

        fetch(server + endpoint, {
            body: data,
            method: 'POST',
            mode: 'cors',
            headers: headers,
            credentials: 'include'
        })
            .then(function(response){
                return response.text();



             /*   if (response.status === 200 || response.status === 0) {
                    // Success!
                    console.log('Success: ' + response.text());
                    return {
                        success: true,
                        text: response.text()
                    };
                } else {
                    // Failure!
                    console.log('Fail: ' + response.statusText);
                    return {
                        success: false,
                        text: response.statusText
                    };

                } */
            } )
            .then(function(rspText){
                // The raw response contains decoded HTML tags... we need to clean that up.

                // Remove dashes from the xml responses... the eventual js object wont like them
                rspText = rspText.replace(/-/g, "");
                // Convert the text response to XML
                var parser = new DOMParser;
                var dom = parser.parseFromString(
                    rspText,
                    'text/html');
                var decodedString = dom.body.textContent;

                // use the DOMParser browser API to convert text to a Document
                var XML = new DOMParser().parseFromString(decodedString, "text/xml");
                // and then use #parse to convert it to a JS object
                var responseXmlObject = parse(XML);
                console.log(responseXmlObject);
                success = true;
                text = responseXmlObject.messages;
                alert(responseXmlObject.messages.messagedetail);
            })
            .catch(function(error) {
                // Networking Failure!
                console.log('NetworkFail: ' + error);
                                success = false;
                text = error;

            });
        //.done();

        console.log({
            success: success,
            text: text
        });
        return {
            success: success,
            text: text
        };

    }
};

【问题讨论】:

  • 您将 fetch 的异步特性与 return 的同步方法混合在一起。您可以让您的 submit 方法返回 fetch 创建的承诺,并在最后一个 then/catch 子句中返回成功对象。
  • @E.Sundin 谢谢;返回由 fetch... 创建的承诺基本上是:return fetch(...) ?假设我遵循这一点——我最终如何使用我的成功对象——我是否需要在持有承诺的 var 上进行交易,或者最后的 then/catch 中的返回是否自动将我的成功对象传递到我返回的任何地方承诺?我希望这是有道理的,这会让人感到困惑:(

标签: javascript reactjs fetch-api


【解决方案1】:

问题是你正在混合异步和同步操作,你应该这样做

processResponse(myResponseObject) {
  this.setState({
    responseAlerts: this.state.responseAlerts.push(myResponseObject)
  });
  console.log('Processing final response. '+ myResponseObject.success + ' ' + myResponseObject.text);
}

sendRequest() {
  N4RecordScan.submit(this.interpolateRequest(), this.state.server, this.state.endpoint)
   .then(function (response){
      this.processResponse(response);
   })
}

,

export const N4RecordScan = {

  submit(data, server, endpoint) {
      let headers = new Headers();
      let success = '';
      let text = '';

      headers.append('Content-Type', 'text/xml');
      headers.append('SOAPAction', 'basicInvoke');
      headers.append('Authorization', 'Basic ' + base64.encode(username + ":" + password));

      let dataPrefix = '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:arg="http://www.navis.com/services/argobasicservice"><soapenv:Header/><soapenv:Body><arg:basicInvoke><arg:scopeCoordinateIds>APMT/USLAX/LAX/LAX</arg:scopeCoordinateIds><arg:xmlDoc><![CDATA[';
      let dataSuffix = ']]></arg:xmlDoc></arg:basicInvoke></soapenv:Body></soapenv:Envelope>';

      data = dataPrefix + data + dataSuffix;

      console.log('about to send ' + data);

      return fetch(server + endpoint, {
          body: data,
          method: 'POST',
          mode: 'cors',
          headers: headers,
          credentials: 'include'
      })
          .then(function(response){
              return response.text();



           /*   if (response.status === 200 || response.status === 0) {
                  // Success!
                  console.log('Success: ' + response.text());
                  return {
                      success: true,
                      text: response.text()
                  };
              } else {
                  // Failure!
                  console.log('Fail: ' + response.statusText);
                  return {
                      success: false,
                      text: response.statusText
                  };

              } */
          } )
          .then(function(rspText){
              // The raw response contains decoded HTML tags... we need to clean that up.

              // Remove dashes from the xml responses... the eventual js object wont like them
              rspText = rspText.replace(/-/g, "");
              // Convert the text response to XML
              var parser = new DOMParser;
              var dom = parser.parseFromString(
                  rspText,
                  'text/html');
              var decodedString = dom.body.textContent;

              // use the DOMParser browser API to convert text to a Document
              var XML = new DOMParser().parseFromString(decodedString, "text/xml");
              // and then use #parse to convert it to a JS object
              var responseXmlObject = parse(XML);
              console.log(responseXmlObject);
              success = true;
              text = responseXmlObject.messages;
              alert(responseXmlObject.messages.messagedetail);
          })
          .catch(function(error) {
              // Networking Failure!
              console.log('NetworkFail: ' + error);
                              success = false;
              text = error;

          })
          .then(function () {
            console.log({
                success: success,
                text: text
            });
            return {
                success: success,
                text: text
            };
          })
      //.done();



  }
};

您应该从 submit 函数中的 fetch 返回承诺,以便 App.js 中的函数可以等到 fetch 完成后再进行处理

【讨论】:

  • 谢谢!那肯定会返回对象!但是,它会在调用 this.processResponse() 的最终 then() 上生成一个新错误。它不能从 then() 中访问“this”吗? ((未捕获(承诺中)TypeError:无法读取未定义的属性'processResponse'))
  • 你可以将this赋值给一个变量let self = this,然后在promise中使用它
  • 找到了——这就是那个问题的答案。很随意! stackoverflow.com/questions/40189424/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-10-14
  • 1970-01-01
  • 1970-01-01
  • 2015-06-25
  • 2018-07-28
  • 2015-06-29
相关资源
最近更新 更多