Promise 和 async/await 使用的小技巧

1,552 阅读2分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

fetch API

我们可以打印一些 fetch web API 可以观察到返回是一个 Promise, 所以对于 fetch 我们可以 Promise 方式调用或者 async/await 方式来调用 fetch API。

console.log(fetch("https://jsonplaceholder.typicode.com/todos/1"))#Promise {<pending>}

这里将 fetch 返回值进行输出查看其结构。

fetch("https://jsonplaceholder.typicode.com/todos/1")
.then(res => console.log(res))

返回一个 Response 对象,其中 ok 表示请求正确返回,status 表示 http 请求的状态,然后要获取数据需要调用其 json 方法来获取数据。

promise.png

Promise 方式 fetch

fetch(url)
    .then(res => res.json())
    .then(data => console.log(data))
    .catch(error => console.log(error))

fetch 是浏览器提供 web API,返回一个 Promise,通过 then 方法可以获取到从服务端返回的对象,调用返回对象的 json() 方法获取数据 json 格式的数据,然后将其返回注意这也是一个 Promise 对象。

async/await 方式 fetch


const loadData = async ()=>{

    const url = "https://jsonplaceholder.typicode.com/todos/1"

    const res = await fetch(url);

    const data = await res.json()

    console.log(data)
}

loadData()

我们可以使用 async/await 方式改写之前的代码,定义函数需要加 async 然后可以在方法内异步函数前面加上 await 这样一来函数看上去好像用于同步方式来异步编程,在 async 函数内部会从上至下,逐行执行,当遇到标记有 await 的函数会等待异步操作完成返回值后继续向下执行。

const loadData = async ()=>{

    try {

        const url = "https://hehejsonplaceholder.typicode.com/todos/1"

        const res = await fetch(url);

        const data = await res.json()

        console.log(data)

    } catch (error) {

        console.log(error)

    }
}

上面代码没有错误进行处理,这里通过 try/catch 来捕捉错误。

const loadData = async ()=>{

    try {

        const url = "https://jsonplaceholder.typicode.com/todos/1"
        const res = await fetch(url);

        console.log(res.ok)

        const data = await res.json()

        return data

    } catch (error) {

        console.log(error)

    }

}

loadData().then(((data)=>console.log(data)))

top-level await

也可以通过 top-level async 这种方式实现在 async 方法以外调用 await 函数得到返回值。

const data = await loadData()
console.log(data)

这样做浏览器会抛出异常

Uncaught SyntaxError: await is only valid in async functions and the top level bodies of modules

暂时我们可以通过下面技巧来实现,

(async ()=>{

    const data = await loadData();
    console.log(data)

})()

Promise.All 并行

我们采用 aync/await 方式进行请求多个数据,不过这些异步请求是一个一个进行的,需要等待前一个异步请求结束再进行下一个,不过 Promise.All 将一组 Promise 进行并行请求后返回数据。

const loadData = async ()=>{


    try {

        const url1 = "https://jsonplaceholder.typicode.com/todos/1"

        const url2 = "https://jsonplaceholder.typicode.com/todos/2"

        const url3 = "https://jsonplaceholder.typicode.com/todos/3"


        const res1 =  await fetch(url1);

        const data1 = await res1.json();

        console.log(data1);

        const res2 =  await fetch(url2);

        const data2 = await res2.json();

        console.log(data2);

        const res3 =  await fetch(url3);

        const data3 = await res3.json();

        console.log(data3);


        // return data

    } catch (error) {

        console.log(error)

    }

}
loadData()

使用 Promise All 对上面代码进行优化。


const loadData = async ()=>{

try {

const url1 = "https://jsonplaceholder.typicode.com/todos/1"

const url2 = "https://jsonplaceholder.typicode.com/todos/2"

const url3 = "https://jsonplaceholder.typicode.com/todos/3"

const results = await Promise.all([

fetch(url1),

fetch(url2),

fetch(url3),

])

const dataPromise = results.map(result=>result.json())

const data = Promise.all(dataPromise)

return data

}catch(err){

console.log(err)

}

}

\


(async ()=>{

const data = await loadData();

console.log(data)

})()