【问题标题】:fetch not working result is undefined in Node.jsfetch not working 结果在 Node.js 中未定义
【发布时间】:2020-06-23 19:06:04
【问题描述】:

我正在运行一个 webhook 以从 Seller.tools api 中提取和处理数据。

我正在尝试使用 node-fetch 调用他们的 api。当我在 cloud9 ide 中对其进行测试时,将其传输到 aws-lambda,无论如何我尝试获取它作为未定义的结果。

事实上,如果我尝试在.then 中调用console.log,它甚至都不会出现。此外,除非我尝试进一步访问结果,否则它甚至不会引发错误。

...
var order, status;
let url='https://data.seller.tools/api/v1/orders/'+orderid;
let options={
  headers:{
    'Authorization':apikey
  }
};

try{
  fetch(url,options)
  .then(res => {status=res.status;order=res.json();return res;})
  .then(res => console.log(res))
  .catch(err => console.error("Err"+err));
}catch(err){console.log(err)}
console.log("order: "+order);
console.log("status: "+status);
console.log(order.order_id);
...

结果:

order: undefined 
status: undefined
{"errorType":"TypeError","errorMessage":"Cannot read property 'order_id' of undefined"}

我在 talend api tester 扩展中使用了相同的 url 和标题,它可以正常工作。但在我的代码中,在 cloud9 ide 中运行测试,它没有。 怎么回事?

【问题讨论】:

  • 我猜是授权密钥的格式。请注意,3xx-5xx 响应不是例外,因此您很可能会得到一些东西,但由于授权失败而没有响应。在 node-fetch npm 站点上,有一组关于如何检查状态错误的说明。 “处理客户端和服务器错误” - 试试看。并且所有最后一个 console.log 语句都将是未定义的,因为您正在进行异步调用。您将在 fetch 返回任何内容之前点击 console.log 语句。
  • 那么如何让我的脚本在继续之前等待响应?
  • 欢迎来到异步 Javascript 的世界!在异步函数中等待结果,或者您需要开始链接承诺调用。 status 和 statusText 是什么?
  • 我在想我正在通过 .then 链接承诺调用。我需要此函数同步工作,以便我可以继续执行脚本。一切都取决于此获取。

标签: node.js aws-lambda aws-cloud9 node-fetch


【解决方案1】:

我设法通过使我的包装函数异步并使用 await 来确保 fetch 同步发生,从而从 fetch 中获得响应。

async function loadJson(url,options) { 
  let response = await fetch(url,options);
  if (response.status == 200) {
    let json = await response.json();
    return {'status':response.status,'json':json};
  }

  throw new Error(response.status);
}
async function getOrder(orderid) {
//...
var order, status;
let url='https://data.seller.tools/api/v1/orders/'+orderid;
let options={
  headers:{
    'Authorization':apikey
  }
};

try{
        var response;

        await loadJson(url,options)
        .then(res => response=res)
        .catch(err => console.log(err)); // Error: 404
        var json = response.json;
        console.log('Order:' + JSON.stringify(json));
        var status=response.status;
        console.log('Status:'+status);
    }catch(err){
        console.log(err);
        return err;
    }
//...
}

日志:

Order: {/*good order info here*/}
Status: 200

不幸的是,这意味着现在包装函数异步工作并返回一个承诺会产生连锁反应。下一步是如何阻止这种涟漪。

【讨论】:

  • 据我发现,没有办法阻止这个“异步/等待周期”。如果有人有解决方案,我将不胜感激。
【解决方案2】:

您应该在 then 方法中进行日志记录,因为调用是异步的,并且日志记录将在调用解决之前发生。


var order, status;
let url = 'https://data.seller.tools/api/v1/orders/' + orderid;
let options = {
  headers: {
    'Authorization': apikey
  }
};

try {
  fetch(url, options)
    .then(res => {
      status = res.status;
      order = res.json();
      console.log("order: " + order);
      console.log("status: " + status);
      console.log(order.order_id);

      return res;
    })
    .catch(err => console.error("Err" + err));
} catch (err) {
  console.log(err)
}

【讨论】:

  • 日志记录并不那么重要(尽管它告诉我变量在哪里)。我想要做的是访问脚本其余部分的响应。我想在继续之前等待收到结果。
猜你喜欢
  • 2018-12-14
  • 1970-01-01
  • 1970-01-01
  • 2016-07-28
  • 1970-01-01
  • 1970-01-01
  • 2017-02-04
  • 2021-07-11
  • 1970-01-01
相关资源
最近更新 更多