Promise和异步操作的问题

时间:2019-06-19 10:01:25

标签: javascript asynchronous promise

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

ContextualVersionConflict: (grpcio 1.21.1 (/usr/local/lib/python2.7/dist-packages), Requirement.parse('grpcio<1.16.0,>=1.0.0'), set(['tooz']))

updatePU函数也是异步函数:

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

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

任何帮助将不胜感激!

1 个答案:

答案 0 :(得分:1)

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

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来报告/处理错误(在第一个代码块中确实存在)。

请参阅***评论,以获取有关此事项和其他一些事项的注释:

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