3、Promise

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

由于 Promise 是 ES6 新增加的,所以一些旧的浏览器并不支持,苹果的 Safari 10 和 Windows 的 Edge 14 版本以上浏览器才开始支持 ES6 特性。

构造 Promise

new Promise(function (resolve, reject) {
    // 要做的事情...
});

Promise 构造函数是 JavaScript 中用于创建 Promise 对象的内置构造函数。

Promise 构造函数接受一个函数作为参数,该函数是同步的并且会被立即执行,所以我们称之为起始函数。起始函数包含两个参数 resolvereject,分别表示 Promise 成功和失败的状态。

起始函数执行成功时,它应该调用 resolve 函数并传递成功的结果。当起始函数执行失败时,它应该调用 reject 函数并传递失败的原因。

Promise 构造函数返回一个 Promise 对象,该对象具有以下几个方法:

注意resolvereject 并不能够使起始函数停止运行,如有需要,别忘了 return

例子

const promise = new Promise((resolve, reject) => {
    // 异步操作
    setTimeout(() => {
      if (Math.random() < 0.5) {
        resolve('success');
      } else {
        reject('error');
      }
    }, 1000);
});
   
promise.then(result => {
  console.log(result);
}).catch(error => {
  console.log(error);
});

Promise 函数

一般情况下,我们将一个 Promise 封装在一个函数中进行返回,例如,在delay时间后,输出message到控制台

function print(delay,message){
    return new Promise(function(resolve,reject){
        setTimeout(function(){
            console.log(message)
        },delay)
    });
}

async 和 await

对于上面的函数,假如我们需要每个一秒输出一段话

function print(delay,message){
    return new Promise(function(resolve,reject){
        setTimeout(function(){
            console.log(message)
            resolve()
        },delay)
    });
}

print(1000,'1')
print(1000,'2')
print(1000,'3')

我们发现,1、2、3 是同时输出的,因为 print 返回的是一个Promise,所以并不会等待前一个 Promise 执行完再执行下一个

这个时候就需要将三个 print 变为同步执行

function print(delay,message){
    return new Promise(function(resolve,reject){
        setTimeout(function(){
            console.log(message)
            resolve()
        },delay)
    });
}

async function test() {
    await print(1000,'1')
    await print(1000,'2')
    await print(1000,'3')
}

test()

注意:await 必须使用在 Promise 对象前,且使用 await 的代码必须在 async 函数中