【问题标题】:Javascript Promise with Fetch results in "undefined" in implementation of Stripe API带有 Fetch 的 Javascript Promise 在 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 的一些怪癖。提前感谢您的帮助。

【问题讨论】:

    标签: javascript c# promise stripe-payments


    【解决方案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

      【讨论】:

        猜你喜欢
        • 2020-12-10
        • 2020-11-06
        • 1970-01-01
        • 2019-08-31
        • 1970-01-01
        • 1970-01-01
        • 2017-09-04
        • 2016-04-28
        • 2022-01-26
        相关资源
        最近更新 更多