FE_Web前端Promise学习理解

Promise是JavaScript中处理异步操作的对象,代表一个异步操作的最终完成或失败。它有三种状态:等待态、执行态和拒绝态,一旦状态改变就不会再变。Promise解决了回调地狱问题,提供了一种更清晰的错误处理机制。通过.then()和.catch()方法可以处理成功和失败的情况,而async/await则进一步简化了异步代码的编写。在实际应用中,Promise常用于文件操作、数据库操作、AJAX请求等异步场景。
摘要由CSDN通过智能技术生成

​ Promise是前端JavaScript中用于处理异步操作的一种对象。比传统的解决方案:回调函数和事件,更合理和更强大。Promise在JavaScript中表示一个异步操作的最终完成(或失败)及其结果值的表示。通俗讲,Promise是对未来事情的承诺,承诺不一定能完成,但是无论是否能完成都会有一个结果。它有三种状态:

  • 等待态(Pending):初始状态,既不是成功也不是失败。
  • 执行态(Fulfilled):表示操作成功完成。
  • 拒绝态(Rejected):表示操作失败。

一旦Promise的状态从pending变为fulfilled或rejected,它就不会再次改变状态。

const fetchData = () => {  
  return new Promise((resolve, reject) => {  
    setTimeout(() => {  
      if (Math.random() < 0.5) {  
        resolve('Data fetched successfully!');  
      } else {  
        reject('Failed to fetch data.');  
      }  
    }, 1000);  
  });  
};  
  
fetchData()  
  .then(data => console.log(data)) // 50% chance of seeing this message  
  .catch(error => console.error(error)); // 50% chance of seeing this message

这段代码中,fetchData函数返回一个Promise对象,模拟了一个异步操作(这里是一个延迟操作)。这个操作有一半的可能性成功,有一半的可能性失败。然后我们使用.then()和.catch()方法来处理成功和失败的两种可能结果。

​ Promise 用来预定一个不一定能完成的任务,要么成功,要么失败。在具体的程序中具体的体现,通常用来封装一个异步任务,提供承诺结果。Promise 是异步编程的一种解决方案,主要用来解决回调地狱的问题,可以有效的减少回调嵌套。真正解决需要配合async/await

Promise对象在JavaScript中用于处理异步操作,它具有以下特点:

  1. 对象状态不受外界影响:Promise对象代表一个异步操作,有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。只有异步操作的结果可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。这也是Promise这个名字的由来,它的英语意思就是“承诺”,表示其他手段无法改变。
  2. 状态改变后无法再变:一旦Promise的状态从pending变为fulfilled或rejected,它就不会再次改变状态。Promise有两种状态的改变:pending→fulfilled和pending→rejected。
  3. ​立即执行:一旦新建Promise就会立即执行,无法中途取消。

Promise的立即执行是指一旦创建Promise对象,就会立即执行相关的异步操作,而不会等待任何代码或事件触发。这是因为Promise对象的创建本质上会立即触发一个异步操作,无论这个操作是否会在将来的某个时间点完成。

举个例子,假设有一个函数foo(),它返回一个Promise对象,这个Promise对象在异步操作成功时resolve,失败时reject。当调用foo()函数时,Promise对象就会被创建,并且相关的异步操作也会立即开始执行。

function foo() {  
  return new Promise((resolve, reject) => {  
    // 异步操作,比如网络请求  
    // ...  
  });  
}  
  
// 调用foo()函数,Promise对象被创建,异步操作立即开始执行  
foo().then(result => {  
  // 异步操作成功,处理结果  
}).catch(error => {  
  // 异步操作失败,处理错误  
});

在这个例子中,foo()函数返回的Promise对象在创建时会立即开始执行其中的异步操作,不管是否有代码或事件触发。这就是为什么说Promise具有立即执行的特点。

  1. 错误处理:如果不设置回调函数callback,Promise抛出的内部错误就不会反应到外部。处于pending状态时,无法得知进行到哪一阶段。

Promise的错误处理是Promise的一个重要特性,它允许您指定一个回调函数来处理Promise操作失败时的错误。

通常,当Promise操作失败时,它会变为rejected状态,并且可以通过.catch()方法来捕获错误。这个方法接受一个回调函数作为参数,并在Promise操作失败时被调用,传递错误信息作为参数。

const promise = new Promise((resolve, reject) => {  
  // 异步操作,可能会失败  
  // ...  
});  
  
promise  
  .then(result => {  
    // 异步操作成功,处理结果  
  })  
  .catch(error => {  
    // 异步操作失败,处理错误  
    console.error(error);  
  });

在这个例子中,当Promise操作失败时,错误会被捕获并传递给.catch()方法的回调函数,然后可以在这个函数中处理错误。如果没有使用.catch()方法来捕获错误,那么Promise错误就会被丢弃,而且你可能永远也看不到错误发生的提示。

另外,Promise的错误处理还有一个重要的特性:它只会处理最近的一个错误。一旦一个Promise操作失败并被捕获,任何其他后续的操作都会被忽略。这是因为一旦Promise变为rejected状态,它就不能再次改变状态。

Promise对象是JavaScript中处理异步操作的一种很好的方式,但它也有一些缺点,包括:

  1. 无法中途取消:一旦新建Promise就会立即执行,无法中途取消。这可能会在某些情况下导致资源浪费或不必要的计算。
  2. 错误处理:如果不设置回调函数,Promise内部抛出的错误不会反应到外部。这可能会导致难以排查的错误和异常。因此,在编写Promise代码时,我们需要特别注意错误处理机制,以便及时发现和解决错误。
  3. 状态管理复杂:当处于padding状态时,无法获取到底是处于哪个阶段,是刚开始还是已经结束。这可能会使得Promise的状态管理变得复杂和混乱。

尽管有这些缺点,但Promise仍然是一种非常有用的异步编程工具,它可以简化异步操作的处理,并提供更好的错误处理机制。在使用Promise时,我们需要尽可能地避免上述问题,并确保代码的可读性和可维护性。

ES6引入的进行异步编程的解决方案,具体表达:从语法上来说, Promise 是一个构造函数;从功能上来说:promise 对象用来封装一个异步操作并可以获取其成功/ 失败的结果值。异步编程包括但不限于:文件操作、数据库操作、AJAX、定时器等。之前进行异步编程直接通过回调函数的方式进行,会导致回调地狱。

  • 回调函数:作为参数的函数
  • 回调地狱:回调函数里面嵌套回调函数
    在这里插入图片描述

1 Promise的初体验

点击按钮, 1s 后显示是否中奖(30%概率中奖)
若中奖弹出 恭喜您中奖
若未中奖弹出 谢谢参与
  • 回调函数的实现方式
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div class="container">
    <h2 class="page-header">Promise初体验</h2>
    <button class="btn btn-primary" id="btn">点击抽奖</button>
</div>
<script type="text/javascript">
    function rand(m, n) {
        return Math.ceil(Math.random() * (n - m + 1) + m - 1);
    }

    const btn = document.querySelector('#btn');
    btn.addEventListener('click', function () {
        setTimeout(() => {
            let number = rand(1, 100);
            console.log(number)
            if (number <= 50) {
                alert('恭喜恭喜,奖品为10万 RMB 劳斯莱斯优惠券')
            } else {
                alert('再接再厉')
            }
        }, 100)
    })

</script>

</body>
</html>

  • promise的实现方式

这是一个基础的 JavaScript Promise 的使用案例。首先,我们需要创建一个函数,它返回一个 Promise,这个 Promise 在一秒钟后解析并返回一个随机的布尔值,代表是否中奖。然后,我们需要在 Promise 解析后处理这个布尔值,如果为 true(即中奖),则显示"恭喜您中奖",否则显示"谢谢参与"。

// 创建一个函数,返回一个 Promise  
function drawLottery() {  
  return new Promise((resolve, reject) => {  
    setTimeout(() => {  
      // 一秒钟后解析 Promise,返回一个随机的布尔值  
      resolve(Math.random() > 0.7);  
    }, 1000);  
  });  
}  
  
// 创建一个按钮,并添加点击事件处理器  
let button = document.createElement('button');  
button.innerText = '抽奖';  
button.addEventListener('click', async () => {  
  let isWinner = await drawLottery(); // 等待 Promise 解析,获取结果  
  if (isWinner) {  
    alert('恭喜您中奖');  
  } else {  
    alert('谢谢参与');  
  }  
});  
  
// 将按钮添加到页面上  
document.body.appendChild(button);
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div class="container">
    <h2 class="page-header">Promise初体验</h2>
    <button class="btn btn-primary" id="btn">点击抽奖</button>
</div>
<script type="text/javascript">
    function rand(m, n) {
        return Math.ceil(Math.random() * (n - m + 1) + m - 1);
    }
    const btn = document.querySelector('#btn');
    // 绑定单机事件
    btn.addEventListener('click', function () {
        // resolve 解决 - 函数类型的数据 - success
        // reject  拒绝 - 函数类型的数据 - fail
        const p = new Promise((resolve, reject) => {
            // Promise 对象 - 可以包裹一个异步任务
            setTimeout(() => {
                let n = rand(1, 100)
                if (n <= 30) {
                    resolve(n) // 将 promise 对象的状态设置为 『成功』
                } else {
                    reject(n) // 将 promise 对象的状态设置为 『失败』
                }
            }, 1000);
        })
        // 调用then方法
        // 成功就调用第一个回调函数,失败调用第二个回调
        p.then((value) => {
            alert('恭喜您中奖,您的中奖号码为' + value);
        }, (reason) => {
            alert('谢谢参与,您的号码为' + reason);
        })
    })

</script>

</body>
</html>

在这里插入图片描述
Promise构造函数的参数通常是一个函数,这个函数接收两个参数:resolve和reject。它们是两个函数,当异步操作完成时,我们调用其中一个。

let promise = new Promise((resolve, reject) => {  
    // 异步操作  
    setTimeout(() => {  
        if (/* 异步操作成功 */) {  
            resolve('成功的结果');  
        } else {  
            reject('失败的原因');  
        }  
    }, 1000);  
});
  • resolve函数:当异步操作成功完成时,我们调用这个函数,并将结果作为参数传递给它。这个参数可以是任何值,包括另一个Promise。
  • reject函数:当异步操作失败时,我们调用这个函数,并将错误信息或错误对象作为参数传递给它。

Promise.then()函数具有两个参数。这两个参数都是可选的,它们都是函数。

  • 第一个参数是一个onFulfilled函数,这个函数将在Promise解析(fulfilled)之后调用,其参数value是Promise的构造函数中回调函数中成功的结果。
  • 第二个参数是一个onRejected函数,这个函数将在Promise被拒绝(rejected)之后调用,其参数reason是Promise的构造函数中回调函数中失败的原因。
let promise = new Promise((resolve, reject) => {  
    // 异步操作  
    setTimeout(() => {  
        if (/* 异步操作成功 */) {  
            resolve('成功的结果');  
        } else {  
            reject('失败的原因');  
        }  
    }, 1000);  
});  
  
promise.then(  
    value => {  
        console.log('Promise was fulfilled with value:', value);  
    },  
    reason => {  
        console.log('Promise was rejected with reason:', reason);  
    }  
);

在这个例子中,如果异步操作成功,我们会在控制台中看到"Promise was fulfilled with value: 成功的结果",如果失败,我们会看到"Promise was rejected with reason: 失败的原因"。

2 fs读取文件-Promise

在Node.js中,您可以使用fs模块中的readFile函数来读取文件,并使用Promise将其包装起来。

const fs = require('fs');  
  
function readFilePromise(filePath) {  
  return new Promise((resolve, reject) => {  
    fs.readFile(filePath, 'utf8', (err, data) => {  
      if (err) {  
        reject(err);  
      } else {  
        resolve(data);  
      }  
    });  
  });  
}  
  
// 使用示例  
readFilePromise('/path/to/file.txt')  
  .then(data => console.log(data))  
  .catch(err => console.error(err));

在这个示例中,我们定义了一个readFilePromise函数,它接收一个文件路径作为参数,并返回一个Promise对象。在函数内部,我们使用fs.readFile函数来读取文件,并将其封装在一个新的Promise中。如果读取成功,我们将Promise解决(resolve)并返回文件内容,否则将Promise拒绝(reject)并返回错误对象。

您可以像使用任何其他Promise一样使用readFilePromise函数,使用.then()方法来处理成功的结果,使用.catch()方法来处理错误。

3 AJAX请求-Promise

AJAX请求可以使用Promise进行处理,以便更好地管理异步操作。使用Promise可以使异步代码看起来更像同步代码,从而简化代码编写和理解。

// 创建一个XMLHttpRequest对象  
var xhr = new XMLHttpRequest();  
  
// 创建一个新的Promise对象  
var promise = new Promise(function(resolve, reject) {  
  // 设置请求方法和URL  
  xhr.open('GET', 'https://api.example.com/data', true);  
  
  // 设置请求成功的回调函数  
  xhr.onload = function() {  
    if (xhr.status === 200) {  
      resolve(xhr.response);  
    } else {  
      reject(new Error('Request failed with status: ' + xhr.status));  
    }  
  };  
  
  // 设置请求错误的回调函数  
  xhr.onerror = function() {  
    reject(new Error('Request failed'));  
  };  
  
  // 发送请求  
  xhr.send();  
});  
  
// 使用then和catch处理Promise对象的结果和错误  
promise.then(function(response) {  
  console.log('Request succeeded', response);  
}).catch(function(error) {  
  console.error('Request failed', error);  
});

在这个示例中,我们创建了一个XMLHttpRequest对象,并使用Promise将其封装起来。在Promise对象的构造函数中,我们设置了请求方法和URL,并定义了请求成功和失败的回调函数。在成功回调函数中,我们使用resolve函数将响应传递给Promise对象,而在失败回调函数中,我们使用reject函数将错误传递给Promise对象。最后,我们使用then和catch方法处理Promise对象的结果和错误。

4 Promise对象状态属性介绍

Promise对象代表一个异步操作的最终完成(或失败)及其结果值。它具有以下几种状态属性:

  1. PromiseState: 这个属性表示Promise对象中函数的执行结果,主要有三种状态,包括pending(等待中)、fulfilled(已完成/已解决)和rejected(已拒绝)。
  2. PromiseValue: 当Promise对象的状态为fulfilled(已完成/已解决)时,PromiseValue属性就是该异步操作的结果值。
  3. PromiseReason: 当Promise对象的状态为rejected(已拒绝)时,PromiseReason属性就是该异步操作报出的错误原因。

一个Promise对象在任何时候只能处于一种状态。一旦状态改变,就不会再变。无论何时,我们都可以获取到Promise对象的结果值或者错误原因。

这些属性的具体表现取决于Promise对象的执行情况。一般来说,当Promise对象执行resolve或者reject函数后,它的状态就会从pending变为fulfilled或rejected,相应的结果值或错误原因也会被设置到对应的属性中。

5 Promise工作流程

let promise = new Promise((resolve, reject) => {  
    // 异步操作  
    setTimeout(() => {  
        if (/* 异步操作成功 */) {  
            resolve('成功的结果');  
        } else {  
            reject('失败的原因');  
        }  
    }, 1000);  
});  
  
promise.then(  
    value => {  
        console.log('Promise was fulfilled with value:', value);  
    },  
    reason => {  
        console.log('Promise was rejected with reason:', reason);  
    }  
);

Promise对象的工作流程可以概括为以下几个步骤:
在这里插入图片描述

  1. 创建 Promise 对象:通过使用 Promise 构造函数创建一个 Promise 对象。这个对象包含一个状态和一个值,初始状态为pending。
  2. 执行 Promise 函数:在 Promise 构造函数中传入一个函数,这个函数会被立即执行,该函数接收两个参数 resolve 和reject,分别表示成功和失败的回调函数。
  3. 执行异步操作:在 Promise 函数中执行异步操作。例如,发送网络请求、读取文件等。
  4. 改变 Promise 状态:当异步操作完成后,调用 resolve 或 reject 函数,改变 Promise对象的状态和值。如果异步操作成功,则调用 resolve 函数并传入成功的结果,将 Promise 对象的状态改fulfilled;如果异步操作失败,则调用 reject 函数并传入失败的原因,将 Promise 对象的状态改为rejected。此时,Promise 的状态被固定,不可再改变。
  5. 处理 Promise 结果:使用 then 方法或 catch 方法处理 Promise 对象的结果。如果 Promise 对象的状态为fulfilled,则调用 then 方法并传入成功的回调函数,该函数接收一个参数,表示异步操作的结果;如果 Promise对象的状态为 rejected,则调用 catch 方法并传入失败的回调函数,该函数接收一个参数,表示异步操作的原因。
  6. 返回 Promise 对象:Promise 对象的 then 方法和 catch 方法都返回一个新的 Promise
    对象,可以继续链式调用 then 方法和 catch 方法,处理异步操作的结果。

以上就是 Promise 的工作流程。需要注意的是,当异步操作完成后,Promise 的状态就不能再改变了。

6 Promise关键问题

6.1 如何修改对象的状态

Promise对象的状态是由Promise的工作流程决定的,一旦状态确定,就不能改变。这意味着你不能直接修改Promise的状态。

Promise有三种状态:pending(待定)、fulfilled(已实现)和rejected(已拒绝)。当Promise创建时,它的状态是pending。当异步操作完成时,如果操作成功,Promise的状态会变为fulfilled;如果操作失败,Promise的状态会变为rejected。一旦状态改变,就不能再改变了。

如果你想改变一个Promise的状态,你可能需要重新考虑你的代码设计。如果你需要在某个操作完成后改变一个对象的状态,你可能需要将这个状态封装在一个独立的对象中,并在Promise完成时更新这个对象的状态。

let obj = { status: 'pending' };  
  
let promise = new Promise((resolve, reject) => {  
  setTimeout(() => {  
    obj.status = 'fulfilled';  
    resolve('Operation completed successfully');  
  }, 1000);  
});  
  
promise.then(() => {  
  console.log(obj.status);  // 'fulfilled'  
});

在这个例子中,我们将状态存储在obj对象中,并在Promise完成时更新这个对象的状态。然后,我们可以在Promise的then回调函数中访问这个新的状态。

6.2 一个Promise指定多个成功/失败的回调函数,都会调用吗?

当 promise 改变为对应状态时都会调用,改变状态后,多个回调函数都会调用,并不会自动停止。

<script>
    let p = new Promise((resolve, reject) => {
        // 改变Promise状态
        resolve('OK');
    });
    ///指定回调函数 - 1
    p.then(value => {
        console.log(value + '-1');
    });
    //指定回调函数 - 2
    p.then(value => {
        console.log(value + '-2');
    });
</script>

在这里插入图片描述

3 改变Promise状态和指定回调函数谁先谁后

问题简化:Promise代码运行时,resolve先执行还是then先执行?

注意,指定回调和执行回调函数是不一样的,指定回调类似于p.then()中声明有哪些回调函数,执行回调则是在状态确定之后执行之前指定的回调.

两种情况都有可能

  • 先改状态再指定回调(同步):改变状态 -->指定回调 并马上执行回调:
  • 先指定回调再改变状态(异步):先指定回调–> 再改变状态 -->改变状态后才进入异步队列执行回调函数

什么时候才能得到数据? - 回调函数什么时候执行

  • 如果先改变状态,那么当指定回调时,回调函数就会被调用,得到数据
  • 如果先指定回调,那么当状态发生改变时,回调函数才被调用得到数据

如下为同步:

<script>
    let p = new Promise((resolve, reject) => {
        resolve('OK');
    });

    p.then(value => {
        console.log(value);
    }, reason => {

    })
</script>

在这里插入图片描述

如下为异步,需等一秒之后执行:
promise执行器中是一个异步任务,那么就执行then,指定回调;处理执行器中的异步任务,1000ms后改变状态;再执行成功的回调函数,得到数据。

<script>
    let p = new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve('OK');
        }, 1000);
    });

    p.then(value => {
        console.log(value);
    }, reason => {

    })
</script>

如下例子:

<script>
    let p = new Promise((resolve, reject) => {
        console.log('同步执行 ... ')
        setTimeout(() => {
            resolve('OK');
        }, 1000);
    });

    p.then(value => {
        console.log(value);
    }, reason => {

    })
</script>

在这里插入图片描述

4 then()方法返回的Promise的对象的状态由什么决定

(1) 简单表达: 由 then()指定的回调函数执行的结果决定
(2) 详细表达:

​ ① 如果抛出异常, 新 promise 变为 rejected, reason 为抛出的异常
​ ② 如果返回的是非 promise 的任意值, 新 promise 变为 resolved, value 为返回的值
​ ③ 如果返回的是另一个新 promise, 此 promise 的结果就会成为新 promise 的结果
<script>
    let p = new Promise((resolve, reject) => {
        resolve('ok');
    });
    // 执行 then 方法
    let result = p.then(value => {
    }, reason => {
    });
    console.log(result);
</script>

在这里插入图片描述
① 如果抛出异常, 新 promise 变为 rejected, reason 为抛出的异常

<script>
    let p = new Promise((resolve, reject) => {
        resolve('ok');
    });
    // 执行 then 方法
    let result = p.then(value => {
        //1. 抛出错误
        throw '出了问题';
    }, reason => {
    });
    console.log(result);
    result.then(value => {}, reason => {
        console.log(reason)
    })
</script>

在这里插入图片描述
② 如果返回的是非 promise 的任意值, 新 promise 变为 resolved, value 为返回的值

<script>
    let p = new Promise((resolve, reject) => {
        resolve('ok');
    });
    let result = p.then(value => {
        return 521;
    }, reason => {
    });
    console.log(result);
    result.then(value => {
        console.log(value)
    }, reason => {

    })
</script>

在这里插入图片描述
③ 如果返回的是另一个新 promise, 此 promise 的结果就会成为新 promise 的结果

<script>
    let p = new Promise((resolve, reject) => {
        resolve('ok');
    });
    let result = p.then(value => {
        return new Promise((resolve, reject) => {
            reject('error');
        });
    }, reason => {
    });
    console.log(result);
    result.then(value => {}, reason => {
        console.log(reason)
    })
</script>

在这里插入图片描述

5 Promise如何串联多个操作任务

(1) promise 的 then()返回一个新的 promise, 可以开成 then()的链式调用
(2) 通过 then 的链式调用串连多个同步/异步任务,这样就能用then()将多个同步或异步操作串联成一个同步队列

<script>
    let p = new Promise((resolve, reject) => {
        setTimeout(() => {
            console.log("first mission")
            resolve("1000ms later resolve");
        }, 1000)
    })
    p.then(value => {
            return new Promise((resolve, reject) => {
                setTimeout(() => {
                    console.log("second mission")
                    resolve();
                }, 1000)
            })
        },
    ).then(value => {
            return new Promise(resolve => {
                setTimeout(() => {
                    console.log("third mission")
                    resolve();
                }, 1000)
            })
        }
    )
</script>

在这里插入图片描述

6 异常穿透

当使用 promise 的 then 链式调用时, 可以在最后指定失败的回调
前面任何操作出了异常, 都会传到最后失败的回调中处理

<script>
    let p = new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve('OK');
        }, 1000);
    });
    p.then(value => {
        console.log(111);
    }).then(value => {
        console.log(222);
    }).then(value => {
        console.log(333);
    }).catch(reason => {   // 在最后指定一个失败的回调
        console.warn(reason);
    });
</script>

在这里插入图片描述

<script>
    let p = new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve('OK');
            // reject('Err');
        }, 1000);
    });
    p.then(value => {
        // console.log(111);
        throw '失败啦!';
    }).then(value => {
        console.log(222);
    }).then(value => {
        console.log(333);
    }).catch(reason => {   // 在最后指定一个失败的回调
        console.warn(reason);
    });
</script>

在这里插入图片描述

7 如何中断promise链
  • 链式调用过程中,我们希望在某一个then()方法的onResolve回调函数调用过程中,中断Promise的链式调用,只需要返回一个状态为pending的Promise对象

当没有明确返回一个promise对象,then()也会返回一个Promise对象,状态为【resolved】,结果为【underfined】

  • 因为then方法的回调函数调用依据是Promise的状态是resolved或者rejected,没有pending对应的回调函数,所以后面的都没法执行了
<script>
    let p = new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve('OK');
        }, 1000);
    });

    p.then(value => {
        console.log(111);
        //有且只有一个方式
        return new Promise(() => {
        });
    }).then(value => {
        console.log(222);
    }).then(value => {
        console.log(333);
    }).catch(reason => {
        console.warn(reason);
    });

</script>

11 async

函数的返回值为 promise 对象,promise 对象的结果由 async 函数执行的返回值决定

和then一样:分成三种情况执行返回值: 是非Promise对象,是一个Promise对象,是抛出异常
<script>
   async function main() {
       return 521
   }
   let res = main();
   console.log(res)
</script>

在这里插入图片描述

<script>
   async function main() {
       return new Promise((resolve, reject) => {
           resolve('OK')
       });
   }
   let res = main();
   console.log(res)
</script>

在这里插入图片描述

<script>
   async function main() {
       return new Promise((resolve, reject) => {
           reject('ERROR')
       });
   }
   let res = main();
   console.log(res)
</script>

在这里插入图片描述

12 await

await 右侧的表达式一般为 promise 对象, 但也可以是其它的值:

  • 如果表达式是 promise 对象, await 返回的是 promise 成功的值
  • 如果表达式是其它值, 直接将此值作为 await 的返回值
    注意:
  • await 必须写在 async 函数中, 但 async 函数中可以没有 await
  • 如果 await 的 promise 失败了, 就会抛出异常, 需要通过 try…catch 捕获处理
<script>
    async function main() {
        let p = new Promise((resolve, reject) => {
            resolve('OK');
        })
        let res = await p;
        console.log(res)
    }
    main();
</script>

在这里插入图片描述

<script>
    function test() {
        return 100;
    }
    async function main() {
        let res = test();
        console.log(res)
    }
    main();
</script>

在这里插入图片描述

<script type="text/javascript">
    async function main() {
        let p = new Promise((resolve, reject) => {
            reject('Error');
        })
        try {
            let res3 = await p;
        } catch (e) {
            console.log(e);
        }
    }
    main()
</script>

在这里插入图片描述

13 async与await结合实践

//回调函数的方式
fs.readFile('D:\\code\\wt-promise\\src\\hello.text', (err, data1) => {
    if (err) throw err;
    fs.readFile('D:\\code\\wt-promise\\src\\hello.text', (err, data2) => {
        if (err) throw err;
        fs.readFile('D:\\code\\wt-promise\\src\\hello.text', (err, data3) => {
            if (err) throw err;
            console.log(data1 + data2 + data3);
        });
    });
});

在这里插入图片描述

//async 与 await
async function main() {
    try {
        // 如果表达式时Promise对象,await返回的Promise成功的值
        let data1 = await mineReadFile('D:\\code\\wt-promise\\src\\hello.text');
        let data2 = await mineReadFile('D:\\code\\wt-promise\\src\\hello.text');
        let data3 = await mineReadFile('D:\\code\\wt-promise\\src\\hello.text');
        console.log(data1 + data2 + data3);
    } catch (e) {
        console.log(e.code);
    }
}
main();

在这里插入图片描述

14 async与await结合发送AJAX请求

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值