前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >JavaScript的异步操作(Promise)

JavaScript的异步操作(Promise)

原创
作者头像
Learn-anything.cn
发布2021-12-17 15:34:12
1.3K0
发布2021-12-17 15:34:12
举报
文章被收录于专栏:learn-anything.cn
一、Promise 是什么?

Promise 是一个用于绑定异步操作与回调函数的对象,让代码更易读且更合理。

1、简单实例
代码语言:txt
复制
<!-- index.html -->
<!DOCTYPE html>
<html lang='zh-CN'>

<head>
    <meta charset="utf-8">
    <title>异步调用</title>

    <script>
        let myFirstPromise = new Promise(function (resolve, reject) {
            setTimeout(function () {
                resolve("成功!");
                // reject("失败");
            }, 2500);
        });

        myFirstPromise
            .then((successMessage) => {
                console.log(successMessage);
            })
            .catch((errorMessage) => {
                console.log(errorMessage);
            });
    </script>

</head>

<body>
    <h1>打开 console 看输出结果!</h1>
</body>

</html>

二、语法说明
1、运行规则

不同于传统的回调, then 关联的函数,会在异步操作完成后执行;如果有多个 then,那么也会依次调用,除非其中有调用 reject 跳转到 catch 。


2、创建 Promise 对象

通过 new 来创建 Promise 对象,当异步操作成功后调用 resolve 来改变 Promise对象的状态;失败后就调用 reject 。

代码语言:txt
复制
const myFirstPromise = new Promise((resolve, reject) => {
    // 做一些异步操作,最终会调用下面两者之一:
    //
    // resolve(someValue);
    // 或
    // reject("failure reason");
});

3、函数拥有 Promise 功能

函数想要拥有 Promise 功能,只需让其返回一个 Promise对象 即可。

代码语言:txt
复制
function myAsyncFunction(url) {
    return new Promise((resolve, reject) => {
				const xhr = new XMLHttpRequest();
        xhr.open("GET", url);
        xhr.onload = () => resolve(xhr.responseText);
        xhr.onerror = () => reject(xhr.statusText);
        xhr.send();
    });
};

4、不使用回调

对 setTimeout 进行 Promise 封装,代码易读且包含异常处理等情况,步骤如下:

代码语言:txt
复制
// 1、过去是用方法
setTimeout(() => saySomething("10 seconds passed"), 10000);

// 2、用 Promise 封装
const wait = ms => new Promise(resolve => setTimeout(resolve, ms));

// 3、以后用这种方式
wait(10000).then(() => saySomething("10 seconds")).catch(failureCallback);

三、静态函数
1、Promise.resolve()

返回一个已处理的 Promise 对象。

代码语言:txt
复制
Promise.resolve("Success").then(function(value) {
  console.log(value); // "Success"
}, function(value) {
  // 不会被调用
});

2、Promise.reject()

返回一个带有拒绝原因的 Promise 对象。

代码语言:txt
复制
Promise.reject(new Error('fail')).then(function() {
  // not called
}, function(error) {
  console.error(error); // Stacktrace
});

3、Promise.all()

等待所有 Promise 对象执行完毕,如果其中任何一个产生 reject ,那么会立即返回。

代码语言:txt
复制
const promise1 = Promise.resolve(3);
const promise2 = 42;
const promise3 = new Promise((resolve, reject) => {
  setTimeout(resolve, 100, 'foo');
});

Promise.all([promise1, promise2, promise3]).then((values) => {
  console.log(values);
});
// expected output: Array [3, 42, "foo"]

4、Promise.race()

同时等待多个 Promise 对象,但只采用其中最先返回的 Promise 对象。

代码语言:txt
复制
const promise1 = new Promise((resolve, reject) => {
  setTimeout(resolve, 500, 'one');
});

const promise2 = new Promise((resolve, reject) => {
  setTimeout(resolve, 100, 'two');
});

Promise.race([promise1, promise2]).then((value) => {
  console.log(value);
  // Both resolve, but promise2 is faster
});
// expected output: "two"

四、async / await
1、概念说明

async / await 建立在 Promise 之上,使异步代码更易于编写和阅读,他们是 ECMAScript 2017 JavaScript版本的新语法。

  • async 怎么使用?

函数声明之前加上 async 关键字,就变成了异步函数了,返回值为promise。

代码语言:txt
复制
let hello = async () => { return "Hello" };
let hello = async function() { return "Hello" };
hello();
  • await 怎么使用?

await 只有用于异步函数才起作用,基于 promise 的函数之前加上 await ,代码会在此行暂停,直到 promise 操作完成,当然其他代码可以继续执行。

代码语言:txt
复制
async function hello() {
  return greeting = await Promise.resolve("Hello");
};

hello().then(alert);

2、async / await 替代 Promise

三种不同方式,实现相同的功能。

  • Promise 的写法
代码语言:txt
复制
fetch('coffee.jpg')
    .then(response => response.blob())
    .then(myBlob => {
        let objectURL = URL.createObjectURL(myBlob);
        let image = document.createElement('img');
        image.src = objectURL;
        document.body.appendChild(image);
    })
    .catch(e => {
        console.log('There has been a problem with your fetch operation: ' + e.message);
    });
  • async / await 的写法
代码语言:txt
复制
async function myFetch() {
    let response = await fetch('coffee.jpg');
    let myBlob = await response.blob();

    let objectURL = URL.createObjectURL(myBlob);
    let image = document.createElement('img');
    image.src = objectURL;
    document.body.appendChild(image);
}

myFetch()
    .catch(e => {
        console.log('There has been a problem with your fetch operation: ' + e.message);
    });
  • 混合使用
代码语言:txt
复制
async function myFetch() {
    let response = await fetch('coffee.jpg');
    return await response.blob();
}

myFetch().then((blob) => {
    let objectURL = URL.createObjectURL(blob);
    let image = document.createElement('img');
    image.src = objectURL;
    document.body.appendChild(image);
})
    .catch((e) =>
        console.log(e)
    );

3、缺陷修正
  • 下面代码完成了同步,但增加了等待时间。
代码语言:txt
复制
<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>Demonstration of slow async/await</title>
</head>

<body>
    <script>
        function timeoutPromise(interval) {
            return new Promise((resolve, reject) => {
                setTimeout(function () {
                    resolve("done");
                }, interval);
            });
        };

        async function timeTest() {
            await timeoutPromise(3000);
            await timeoutPromise(3000);
            await timeoutPromise(3000);
        }

        let startTime = Date.now();
        timeTest().then(() => {
            let finishTime = Date.now();
            let timeTaken = finishTime - startTime;
            alert("Time taken in milliseconds: " + timeTaken);
        })
    </script>
</body>

</html>
  • 简单修改上面,即可提高性能
代码语言:txt
复制
<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>Demonstration of fast async/await</title>
</head>

<body>
    <script>
        function timeoutPromise(interval) {
            return new Promise((resolve, reject) => {
                setTimeout(function () {
                    resolve("done");
                }, interval);
            });
        };

        async function timeTest() {
            const timeoutPromise1 = timeoutPromise(3000);
            const timeoutPromise2 = timeoutPromise(3000);
            const timeoutPromise3 = timeoutPromise(3000);

            await timeoutPromise1;
            await timeoutPromise2;
            await timeoutPromise3;
        }

        let startTime = Date.now();
        timeTest().then(() => {
            let finishTime = Date.now();
            let timeTaken = finishTime - startTime;
            alert("Time taken in milliseconds: " + timeTaken);
        })
    </script>
</body>

</html>

五、其他异步操作
1、setTimeout

setTimeout :在指定时间后执行一次;

代码语言:txt
复制
<!DOCTYPE html>
<html lang="en-US">

<head>
    <meta charset="utf-8">
    <title>Person greeter app</title>
</head>

<body>
    <script>
        let myGreeting = setTimeout(function () {
            alert('Hello, Mr. Universe!');
        }, 2000)

        // 在超时前关闭计时器
        // clearTimeout(myGreeting);
    </script>
</body>

</html>

2、setInterval

在指定的时间间隔,不停重复运行。

代码语言:txt
复制
<!DOCTYPE html>
<html lang="en-US">

<head>
    <meta charset="utf-8">
    <title>Simple setInterval clock</title>
    <style>
        p {
            font-family: sans-serif;
        }
    </style>
</head>

<body>
    <p class="clock"></p>
    <script>
        function displayTime() {
            let date = new Date();
            let time = date.toLocaleTimeString();
            document.querySelector('.clock').textContent = time;
        }

        const createClock = setInterval(displayTime, 1000);

        // 关闭 Interval
        // clearInterval(myInterval);
    </script>
</body>

</html>

六、参考文档

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、Promise 是什么?
    • 1、简单实例
    • 二、语法说明
      • 1、运行规则
        • 2、创建 Promise 对象
          • 3、函数拥有 Promise 功能
            • 4、不使用回调
            • 三、静态函数
              • 1、Promise.resolve()
                • 2、Promise.reject()
                  • 3、Promise.all()
                    • 4、Promise.race()
                    • 四、async / await
                      • 1、概念说明
                        • 2、async / await 替代 Promise
                          • 3、缺陷修正
                          • 五、其他异步操作
                            • 1、setTimeout
                              • 2、setInterval
                              • 六、参考文档
                              领券
                              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档