获取调用和承诺链接的问题 [英] Problem with fetch calls and promise chaining

查看:50
本文介绍了获取调用和承诺链接的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

**后端有问题

所以我一直在链接 promise 时遇到问题.我放弃了 axios 和 async await 回去重新学习基础知识,因为我一定是在某个地方犯了一个简单的错误,但我没有运气.希望有人可以看看吗?

So I've been having a problem with chaining promises. I ditched axios and async await to go back to re-learn the basics, as I must be making a simple mistake somewhere, but I've had no luck. Was hoping someone could take a look?

我按以下顺序调用以下路由:

I'm calling the following routes in the following order:

  1. /users/register
  2. /users/all
  3. /delete/:id
  4. /users/all

问题是代码应该添加一个用户,然后删除同一个用户,但我会在每 6 个左右的调用中说 1 个,第 2 步和第 4 步(显示所有用户)都显示新添加的用户- 这是不正确的.

The problem is that the code should add a user, and then delete that same user, but I'd say 1 in every 6 or so calls, both step 2 and step 4 (displaying all users) show the newly added user - which isn't correct.

但据我所知,我正确地将承诺和调用链接在一起.

But as far as I can see I'm chaining the promises and calls together correctly.

我肯定漏掉了一些明显的东西,但我真的看不到.希望有第二双眼睛或方向来告诉我我哪里出错了

I must be missing something obvious, but I really can't see it. Would appreciate a second pair of eyes or direction as to where I'm going wrong

    function test() {
        fetch(`http://localhost:8080/users/register`, {        **//1**
            method: 'POST',
            mode: 'cors',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify({ firstName: 'nick', lastName: 'smith', phone: '01980635243', email: 'nick@hotmail.com', password: '1234567891011', confirmPassword:'1234567891011'})
        })
        .then(res => res.json())
        .then(res => {
            console.log(res);
            return fetch('http://localhost:8080/users/all')    **//2**
        })
        .then(res => res.json())
        .then(res => {
            console.log(res)
            return fetch('http://localhost:8080/users/delete-email/nick@hotmail.com', {  **//3**
                method: 'DELETE',
                mode: 'cors',
                headers: {
                    'Content-Type': 'application/json'
                }
            });
        })
        .then(res => res.json()) 
        .then(res => {
            console.log(res)
            return fetch('http://localhost:8080/users/all');    **//4**
        })
        .then(res => res.json())
        .then(res => console.log(res))
        .catch(err => console.log(err));
    }

推荐答案

很适合您退后一步,真正专注于学习基础知识.你应该知道 fetch 是一个低级接口,按原样使用它是一个菜鸟.编程就是让您的生活更轻松.如果需要处理JSON,我们写一个fetchJSON特化-

Good for you to take a step back and really focus on learning the basics. You should know that fetch is a low-level interface and it's a rookie move to use it as-is. Programming is all about making your life easier. If you need to deal with JSON, let's write a fetchJSON specialization -

const fetchJson = (url, opts = {}) =>
  fetch(url, { ...opts, headers: 'Content-Type': 'application/json' })
    .then(r => r.json())

即使有我们的助手,我们也不应该直接使用它.通过定义可重用的函数,我们的代码变得更具描述性且更易于使用 -

Even with our helper, we shouldn't jump to use it directly. By defining reusable functions, our code becomes more descriptive and easier to use -

const userList = () =>
  fetchJson(`http://localhost:8080/users/all`)

创建userRegister 函数也很简单-

const userRegister = (user = {}) =>
  fetchJson
    ( `http://localhost:8080/users/register`
    , { method: "POST", mode: "cors", body: JSON.stringify(user) }
    )

最后userDelete -

const userDelete = email =>
  fetchJson
    ( `http://localhost:8080/users/delete-email/${email}`
    , { method: "DELETE", mode: "cors" }
    )

现在我们可以把它们放在一起

Now we can put it all together

const test = () =>
  userRegister({
    firstName: 'nick',
    lastName: 'smith',
    phone: '01980635243',
    email: 'nick@hotmail.com',
    password: '1234567891011',
    confirmPassword:'1234567891011'
  })
  .then(user => {
    console.log("registered", user)
    return userList()
  })
  .then(users => {
    console.log("list", users)
    return userDelete("nick@hotmail.com")
  })
  .then(_ =>
    console.log("user deleted")
    return userList()
  })

请注意,我们没有将任何 .catch 附加到 test.这是留给调用者决定的.我们可以像这样运行测试 -

Notice we don't attach any .catch to the test. This is left for the caller to decide. We could run the test like this -

test().then(console.log, console.error)

不要停在那里

你看到.then(something => { console.log(something), ... })的模式了吗?我们可以创建一个通用的log函数,使这个意图更加清晰 -

Do you see the pattern of .then(something => { console.log(something), ... }). We could make a generic log function that makes this intention more clear -

const log = label => data =>
{ console.log(label, data)
  return data
}

const test = () =>
  userRegister({
    firstName: 'nick',
    lastName: 'smith',
    phone: '01980635243',
    email: 'nick@hotmail.com',
    password: '1234567891011',
    confirmPassword:'1234567891011'
  })
  .then(log("registered"))
  .then(_ => userList())
  .then(log("list"))
  .then(_ => userDelete("nick@hotmail.com"))
  .then(log("user deleted"))
  .then(_ => userList())

但是这里有一个不好的做法.console.log 是一个副作用,如果我们能从 test 中得到 each 承诺的结果,那就太好了.我们可以清楚地看到 _ =>... 正在替换链中前一个 promise 的值,并且只有 final promise 值对调用者可用.

But there's a bad practice here. console.log is a side effect and it would be nice if we could get the result of each promise back from the test. We can plainly see that _ => ... is replacing the value of the previous promise in the chain and only the final promise value will be available to the caller.

可以将所有结果附加到一个数组中,并将该数组贯穿到每个连续的 promise,但这也相当乏味.这尤其适用于 asyncawait 的帮助,因为它们使承诺值在同一范围内可用 -

You could append all the results to an array and thread the array through to each successive promise, but this is also rather tedious. This is particularly where async and await are helpful as they make promise values available in the same scope -

async function test()
{ const user = await userRegister({
    firstName: 'nick',
    lastName: 'smith',
    phone: '01980635243',
    email: 'nick@hotmail.com',
    password: '1234567891011',
    confirmPassword:'1234567891011'
  })

  const list1 = await userList()

  const delete = await userDelete("nick@hotmail.com")

  const list2 = await userList()

  return [user, list1, deleted, list2] // <- all results
}

现在 console.log 已经与 test 分离,并且 all 承诺值的结果可供调用者使用

Now console.log has been disentangled from test and the result of all promise values is available to the caller

test().then(console.log, console.error)

这篇关于获取调用和承诺链接的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆