带有 Fetch 的 Javascript Promise 在 Stripe API 的实现中导致“未定义”

Posted

技术标签:

【中文标题】带有 Fetch 的 Javascript Promise 在 Stripe API 的实现中导致“未定义”【英文标题】:Javascript Promise with Fetch results in "undefined" in implementation of Stripe API 【发布时间】:2021-05-08 03:00:47 【问题描述】:

我正在尝试在我的网站中实现 Stripe 支付 API。但是,我对 javascript 不是很熟悉,这导致了一些问题。

我的大部分代码取自Stripe's website,做了一些修改以更好地适应我自己的网站。

我有一个函数CreateCustomer,旨在根据表单的输入创建客户:

        async function createCustomer () 
            var emailJSON = 
                "email": `$document.querySelector('#email-field').value`
            ;

             const output = await fetch('/create-customer', 
                method: 'post',
                headers: 
                    'Content-Type': 'application/json',
                ,
                body: JSON.stringify(emailJSON)
            )
                .then((response) => 
                    return response.json();
                )
                .then((result) => 
                    return result;
                );

            return output;

        

这个函数被另一个函数调用,并且输出被存储,因为我有另一个需要客户 ID 的函数。

var handleForm = function () 

// other code

const customerPromise = createCustomer();
var customer = customerPromise.data;

// more code

CreateCustomer 中的 fetch 调用调用以下 C# 代码:

  [Route ("create-customer")]
  [ApiController]
  public class CustomerCreationController : Controller
  
    [HttpPost]
    public ActionResult Create(CustomerCreateRequest request)
    
      var customers = new CustomerService();
      var customer = customers.Create(new CustomerCreateOptions
      
        Email = request.Email,
      );

      return Json(new  _customer = customer.Id );
    

    public class CustomerCreateRequest
    
      [JsonProperty("email")]
      public string? Email  get; set; 
    
  

根据我对 Promise 的了解,如果我在 Promise 解决之前调用它,我将得到“未定义”。但我也认为我明白,如果我等待承诺(就像我在CreateCustomer 中所做的那样),这应该不是问题。但是,每当我运行此代码时,我最终都会在 handleFormcustomer 变量中保存 undefined。

就像我说的,我对 JavaScript 很不熟悉,所以问题可能是我忽略的语言和/或 Promises 的一些怪癖。提前感谢您的帮助。

【问题讨论】:

【参考方案1】:

如果您的createCustomer 是异步的,则在调用它时需要等待它:

var handleForm = async function () 
  // other code

  const customerPromise = await createCustomer();
  var customer = customerPromise.data;

  // more code

【讨论】:

【参考方案2】:

@Marco 是正确的。

你也做 await 和包括 .then 女巫是多余的。

以下是您的承诺选项:

// Using async/await
async function createCustomer () 
  try 
    const requestBody = 
      email: `$document.querySelector('#email-field').value`
    ;

    const response = await fetch('/create-customer', 
      method: 'post',
      headers:  'Content-Type': 'application/json' ,
      body: JSON.stringify(requestBody)
    )
    const data = await response.json()
    return data;
   catch (error) 
    console.error(error);
  
  


/*
If you are calling createCustomer somewhere it has to
either be a async function to allow await, or
use .then((data) => console.log(data))
*/
const data = await createCustomer();
// Promise chains
async function createCustomer (callback) 
  const requestBody = 
    email: `$document.querySelector('#email-field').value`
  ;

  fetch('/create-customer', 
    method: 'post',
    headers:  'Content-Type': 'application/json' ,
    body: JSON.stringify(requestBody)
  )
  .then(response => response.json())
  .then(data => callback(data))
  .catch(e => console.error(e))


createCustomer((data) => 
  // do something with data
)

fetch 的一个小问题是您还必须等待 .json() 调用。因为这也是一个承诺。 如果您正在执行大量网络请求,请查看axios

【讨论】:

以上是关于带有 Fetch 的 Javascript Promise 在 Stripe API 的实现中导致“未定义”的主要内容,如果未能解决你的问题,请参考以下文章

带有 Fetch 的 Javascript Promise 在 Stripe API 的实现中导致“未定义”

在本地主机上运行的 Vue 应用程序中使用带有 php 文件的 JavaScript fetch() - 相对 URL 问题

Ant Design Pro V5 代理设置(javascript版)

javascript fetch 响应 403 错误

将带有 fetch 的 POST 发送到烧瓶时的端口问题

在 JavaScript 中使用 fetch() 时,如何将返回对象的详细信息呈现到 html 页面上