【问题标题】:Promise.all not waiting for Promise to resolvePromise.all 不等待 Promise 解决
【发布时间】:2020-06-23 00:29:35
【问题描述】:

当我向服务器发出请求时,数据作为包含正确数据的承诺(如预期)返回,但由于某种原因,程序无法正确执行。

此外,该程序在我将其上传到 Zeit 之前就可以运行。

获取请求:

1) 我知道我不需要“内容类型”:“应用程序/json”。删除它不会影响程序。

2) 这是一个 GET 请求,端点工作正常。另外,当我在 Postman 中执行同样的请求时,我得到了正确的结果。

// CODE ABOVE DOES NOT MATTER
       .then( ([hours, employees, dayLabor]) => {
           // hours, employees, and dayLabor are empty lists for this exercise '[]'

            let business = fetch(`${config.URL}/${TokenService.getId()}`,
            {
                headers: {
                    'content-type': 'application/json',
                    'table':'business',
                    'Authorization':`bearer ${TokenService.getAuthToken()}`
                }
            })
            .then(data => {
              console.log('business: ',data, ' or ', data.json());
              if (!data.ok){
                  return data.json().then(e => Promise.reject(e));}

              return data.json();
            });


            return Promise.all([business, hours, employees, dayLabor]);
      })
      .then( ([business, hours, employees, dayLabor]) => {  
            // THIS is never executed?

            console.log('completed');            

            //fetch has been completed and the state has been updated so set "fetched" to true

            this.setState({business, hours, employees, 'dayLabor': dayLabor.length>0? this.sort(dayLabor):[], fetched: true});


      })
      .catch(error => {
            console.error({error});
      });

输出结果(出于隐私原因删除了网址):

business:  
Response {type: "cors", url: "https://xxxxxx.herokuapp.com/1", redirected: false, status: 200, ok: true, …}
type: "cors"
url: "https://xxxxxxxx.herokuapp.com/1"
redirected: false
status: 200
ok: true
statusText: "OK"
headers: Headers {}
body: (...)
bodyUsed: true
__proto__: Response
  or  
Promise {<pending>}
__proto__: Promise
[[PromiseStatus]]: "resolved"
[[PromiseValue]]: Array(1)
0: {id: 1, business_name: "Fake Company Inc"}
length: 1
__proto__: Array(0)

我想访问“[[PromiseValue]]”中的对象。我很困惑为什么这不起作用,尤其是当我在本地运行它时它确实起作用了?似乎问题在于“业务”变量或“Promise.all”没有等待承诺解决。

任何帮助将不胜感激,我一直在搜索,但找不到任何解决方案。

【问题讨论】:

    标签: javascript reactjs promise frontend es6-promise


    【解决方案1】:

    一个特殊的问题是您只能调用一次data.json()。它读取 http 响应的其余部分(正文),然后对其进行解析)。一旦读过,就不能再读了。所以,当你这样做时:

    console.log(..., data.json())
    

    您正在指示响应对象读取响应正文并返回一个承诺,该承诺将告诉您何时完成。然后,您记录尚未履行的承诺。然后,你把这个承诺丢在地上,永远不要做任何事情。

    然后,稍后在您的代码中,您可以这样做

    return data.json();
    

    但是,没有更多的响应正文,它已经被读取了。您不能多次调用它。所以,这行不通。

    因此,首先要解决的问题是从您的 console.log() 中删除 data.json() 并让

    return data.json();
    

    处理一次读取正文并解析响应。

    所以,改成这样:

       // CODE ABOVE DOES NOT MATTER
       .then( ([hours, employees, dayLabor]) => {
           // hours, employees, and dayLabor are empty lists for this exercise '[]'
    
            let business = fetch(`${config.URL}/${TokenService.getId()}`,
            {
                headers: {
                    'content-type': 'application/json',
                    'table':'business',
                    'Authorization':`bearer ${TokenService.getAuthToken()}`
                }
            }).then(data => {
              console.log('business: ', data);
              if (!data.ok){
                  return data.json().then(e => Promise.reject(e));}
    
              return data.json();
            });
    
    
            return Promise.all([business, hours, employees, dayLabor]);
      }).then( ([business, hours, employees, dayLabor]) => {  
            // THIS is never executed?
    
            console.log('completed');            
    
            //fetch has been completed and the state has been updated so set "fetched" to true
    
            this.setState({business, hours, employees, 'dayLabor': dayLabor.length>0? this.sort(dayLabor):[], fetched: true});
    
    
      }).catch(error => {
            console.error({error});
      });
    

    【讨论】:

    • 哇!两周前我在服务器端工作时遇到了同样的问题,不敢相信我忘记了这个(facepalm)。我很感激你的回答人!我在这个lol上浪费了太多时间
    • @ezg - 这很微妙。如果您尝试多次调用.json(),如果Response 对象抛出一个非常具体的异常,那实际上会很好。这将为人们节省大量时间。在我意识到这个实际问题之前,我看了你的代码 5 次并且有其他几个理论。这是微妙的。无论如何,很高兴能提供帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-02
    • 2017-09-10
    • 1970-01-01
    • 1970-01-01
    • 2021-05-19
    • 1970-01-01
    相关资源
    最近更新 更多