End

JavaScript 异步 Promise await

本文地址

JavaScript 异步 Promise await

setTimeout(function () {
    console.log("delay")
}, 1000);

setTimeout(() => console.log("delay2"), 1200);

fetch("https://www.wanandroid.com//hotkey/json", { method: 'GET' })
    .then(response => response.text())
    .then(result => console.log(result))
    .catch(error => console.log('error', error));

Promise

Promise 是 ECMAScript 6 提供的类,目的是更加优雅地书写复杂的异步任务。

  • Promise 构造函数接受一个函数(起始函数)作为参数,该函数是同步的并且会被立即执行
  • 起始函数执行成功时,需调用 resolve 函数并传递成功的结果
  • 起始函数执行失败时,需调用 reject 函数并传递失败的原因,一般会传递一个异常

Promise 有以下几个方法:

  • then:用于处理 Promise 成功状态的回调函数
  • catch:用于处理 Promise 失败状态的回调函数
  • finally:无论 Promise 是成功还是失败,都会执行的回调函数

.then() 传入的函数会按顺序依次执行,有任何异常都会直接跳到 catch 序列。

resolve() 中可以向下一个 then 传递一个值,then 中也可以返回一个值传递给下一个 then。

常见问题:

Q: then、catch 和 finally 序列能否顺序颠倒?
A: 可以,但不建议。

Q: 除了 then 块以外,其它两种块能否多次使用?
A: 可以,finally 与 then 一样会按顺序执行,但是 catch 块只会执行第一个,除非 catch 块里有异常。

Q: then 块如何中断?
A: then 块默认会向下顺序执行,return 是不能中断的,可以通过 throw 来跳转至 catch 实现中断。

Q: 什么时候适合用 Promise 而不是传统回调函数?
A: 当需要多次顺序执行异步操作的时候,例如,需要先异步检测用户名,然后再异步检测密码。

Q: Promise 是一种将异步转换为同步的方法吗?
A: 完全不是。Promise 只不过是一种更良好的编程风格。

Q: 什么时候我们需要再写一个 then 而不是在当前的 then 接着编程?
A: 当你又需要调用一个异步任务的时候。

异步函数

异步函数中可以使用 await 指令,await 指令后必须跟着一个 Promise,异步函数会在这个 Promise 运行中暂停,直到其运行结束再继续运行。

异步函数实际上原理与 Promise 原生 API 的机制是一模一样的,只不过更便于程序员阅读。

如果 Promise 有一个正常的返回值,await 语句也会返回它。

async function asyncFunc() {
    let value = await new Promise((resolve, reject) => resolve("返回值"));
    console.log(value);
}
asyncFunc();

异步案例

要求:100 毫秒后输出 First,200 毫秒后输出 Second,300 毫秒后输出 Third。

function getRandomInt(tag) {
    let result = Math.floor(Math.random() * 10)
    console.log(`${Date.now()} ${tag} ${result}`);
    return result;
}

原始方案

setTimeout(() => {
    let v1 = getRandomInt("First")
    setTimeout(() => {
        let v2 = getRandomInt("Second")
        setTimeout(() => {
            let v3 = getRandomInt("Third")
            console.log(`${v1}-${v2}-${v3}`)
        }, 100);
    }, 100);
}, 100);

使用 Promise

new Promise((resolve, reject) =>
    setTimeout(() => resolve(getRandomInt("First")), 100)
).then((v1) => new Promise((resolve, reject) =>
    setTimeout(() => resolve([v1, getRandomInt("Second")]), 100)
)).then((v1v2) => setTimeout(() => {
    let v3 = getRandomInt("Third")
    console.log(`${v1v2[0]}-${v1v2[1]}-${v3}`)
}, 100))

使用异步函数

async function asyncFunc() {
    let v1 = await new Promise((resolve, reject) =>
        setTimeout(() => resolve(getRandomInt("First")), 100)
    )
    let v2 = await new Promise((resolve, reject) =>
        setTimeout(() => resolve(getRandomInt("Second")), 100)
    )
    setTimeout(() => {
        let v3 = getRandomInt("Third")
        console.log(`${v1}-${v2}-${v3}`)
    }, 100)
}

2017-10-15

posted @   白乾涛  阅读(1770)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
· 使用C#创建一个MCP客户端
点击右上角即可分享
微信分享提示