Promise
、async/await
的使用Promise
async/await
Promise
Promise
?Promise
是异步编程的一种解决方案,它代表了一个异步操作的最终结果。它是一个对象,用来传递异步操作的消息,而不是直接传递结果。
Promise
提供统一的 API
,各种异步操作都可以用同样的方法进行处理,并提供统一的接口。Promise
也有三种状态:
Pending
(等待中):初始状态,既没有完成也没有失败。Fulfilled
(已完成):操作成功完成。Rejected
(已失败):操作失败。Promise
的特点Pending
(等待中)、Fulfilled
(已完成)和 Rejected
(已失败)。只有异步操作的结果,才会改变 Promise 的状态。Promise
实例代表的异步操作,一旦异步操作完成,就不会再变,任然是 Pending
状态。Promise
对象的 then
方法是定义在原型上面的,可以把多个 Promise
实例进行链式调用。Promise
对象的 catch
方法是定义在原型上面的,可以捕获 Promise
实例中发生的错误。Promise
对象的 finally
方法是定义在原型上面的,不管 Promise
实例最后状态如何,都会执行指定的回调函数。Promise
实例的构造函数接受一个执行器函数,该函数的两个参数分别是 resolve
和 reject
。resolve
用于将 Promise
对象的状态从 Pending
变为 Fulfilled
,reject
用于将 Promise
对象的状态从 Pending
变为 Rejected
。Promise
的基本用法// 创建一个Promise实例
const promise = new Promise((resolve, reject) => {
// 异步操作成功时调用resolve函数
resolve('success');
// 异步操作失败时调用reject函数
reject('error');
});
// 处理Promise对象的状态改变
promise.then(value => {
console.log(value); // "success"
}).catch(error => {
console.log(error); // "error"
});
Promise
的链式调用// 创建Promise实例
const promise1 = new Promise((resolve, reject) => {
resolve('success1');
});
// 链式调用
promise1.then(value => {
console.log(value); // "success1"
return 'success2';
}).then(value => {
console.log(value); // "success2"
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('success3');
}, 1000);
});
}).then(value => {
console.log(value); // "success3"
}).catch(error => {
console.log(error);
});
Promise
的错误处理// 创建Promise实例
const promise = new Promise((resolve, reject) => {
throw new Error('error');
});
// 处理Promise对象的状态改变
promise.then(value => {
console.log(value);
}).catch(error => {
console.log(error); // "error"
});
Promise
的 finally
方法finally
方法的作用finally
方法用于指定不管 Promise
实例最后状态如何,都会执行指定的回调函数。
finally
方法的用法// 创建Promise实例
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('success');
}, 1000);
});
// 处理Promise对象的状态改变
promise.then(value => {
console.log(value); // "success"
}).catch(error => {
console.log(error);
}).finally(() => {
console.log('finally');
});
Promise
的状态变化const promise = new Promise((resolve, reject) => {
// 异步操作成功时调用resolve函数
resolve('success');
// 异步操作失败时调用reject函数
reject('error');
});
// 处理Promise对象的状态改变
promise.then(value => {
console.log(value); // "success"
}).catch(error => {
console.log(error); // "error"
});
Promise
的缺点Promise
,一旦新建就会立即执行,无法中途取消。Promise
内部抛出的错误,不会反应到外部。Pending
状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。Pending
状态,导致程序运行阻塞。async/await
async/await
是什么?async/await
是 ECMAScript 2017
引入的异步编程语法,它是 Promise
的语法糖。
async/await
让异步操作变得更加方便,让代码更简洁,更易读。
async/await
就是 Generator
函数和 Promise
的组合。
async/await
关键字会自动执行 Generator
函数,并返回一个 Promise
对象。async/await
更容易理解和编写。async/await
适用于大多数异步操作,不仅仅局限于 Generator
函数。Promise
对象的错误。async/await
的基本用法async function hello() {
return 'hello world';
}
hello().then(value => {
console.log(value); // "hello world"
});
async/await
的链式调用async function hello() {
return 'hello';
}
async function world() {
return 'world';
}
async function helloWorld() {
const helloValue = await hello();
const worldValue = await world();
return `${helloValue} ${worldValue}`;
}
helloWorld().then(value => {
console.log(value); // "hello world"
});
async/await
的错误处理async function hello() {
throw new Error('error');
}
hello().then(value => {
console.log(value);
}).catch(error => {
console.log(error); // "error"
});
async/await
的 finally
方法async function hello() {
return 'hello';
}
async function world() {
return 'world';
}
async function helloWorld() {
const helloValue = await hello();
const worldValue = await world();
return `${helloValue} ${worldValue}`;
}
helloWorld().then(value => {
console.log(value); // "hello world"
}).finally(() => {
console.log('finally');
});
async/await
的缺点async/await
,一旦开始就会执行,无法中途取消。Promise
友好。Generator
函数友好。Generator
函数Generator
函数?Generator
函数是一种异步编程解决方案,它是一种特殊的函数,它返回一个可迭代对象(Iterator
)。
Generator
函数是一个状态机,封装了多个内部状态。
Generator
函数运行后,返回一个遍历器对象,可以依次遍历 Generator
函数内部的每一个状态。
Generator
函数可以暂停函数执行的位置,返回后续的执行结果。
Generator
函数可以让异步操作更加方便。
Generator
函数的特点Generator
函数是一个状态机,封装了多个内部状态。Generator
函数运行后,返回一个遍历器对象,可以依次遍历 Generator
函数内部的每一个状态。Generator
函数可以暂停函数执行的位置,返回后续的执行结果。Generator
函数可以暂停函数执行的位置,返回后续的执行结果。Generator
函数可以方便地实现异步操作。Generator
函数的基本用法function* helloWorld() {
yield 'hello';
yield 'world';
}
const hw = helloWorld();
hw.next().value; // "hello"
hw.next().value; // "world"
hw.next().value; // undefined
Generator
函数的错误处理function* helloWorld() {
yield 'hello';
throw new Error('error');
yield 'world';
}
const hw = helloWorld();
hw.next().value; // "hello"
hw.next().value; // Uncaught Error: error
Generator
函数的 yield*
语句yield*
语句可以将另一个 Generator
函数的执行结果,赋值给当前 Generator
函数的执行结果。
function* hello() {
yield 'hello';
}
function* world() {
yield 'world';
}
function* helloWorld() {
yield* hello();
yield* world();
}
const hw = helloWorld();
hw.next().value; // "hello"
hw.next().value; // "world"
hw.next().value; // undefined
Generator
函数的 return
语句Generator
函数如果使用 return
语句,函数执行结束,且返回给定的值。
function* helloWorld() {
yield 'hello';
return 'world';
}
const hw = helloWorld();
hw.next().value; // "hello"
hw.next().value; // "world"
hw.next().value; // undefined
Generator
函数的 throw
语句Generator
函数如果使用 throw
语句,函数会抛出错误,并中断执行。
function* helloWorld() {
yield 'hello';
throw new Error('error');
yield 'world';
}
const hw = helloWorld();
hw.next().value; // "hello"
hw.next().value; // Uncaught Error: error
hw.next().value; // undefined
Generator
函数的 next
方法Generator
函数的 next
方法可以手动控制 Generator
函数的执行。
function* helloWorld() {
try {
yield 'hello';
yield 'world';
} catch (e) {
console.log(e);
}
}
const hw = helloWorld();
hw.next().value; // "hello"
hw.next().value; // "world"
hw.next(); // { value: undefined, done: true }
Generator
函数的 for...of
循环Generator
函数可以通过 for...of
循环来遍历执行。
function* helloWorld() {
yield 'hello';
yield 'world';
}
for (let value of helloWorld()) {
console.log(value);
}
// "hello"
// "world"
Generator
函数的缺点Generator
函数只能使用 for...of
循环来遍历,无法使用 next
方法来手动控制执行。Generator
函数内部只能使用 yield
语句,不能使用 return
语句返回值。Generator
函数内部的错误无法被捕获,只能在函数外部使用 try...catch
语句捕获。Generator
函数没有自己的 this
,所以无法用作类的构造函数。Generator
函数的执行必须靠执行器,所以不适合在服务端使用。async/await
和 Generator
函数的区别async/await
和 Generator
函数的区别主要有以下几点:
async/await
是 Promise
的语法糖,Generator
函数是 Iterator
的语法糖。async/await
更简洁,更易读,内置执行器,更方便处理错误。async/await
适用于大多数异步操作,不仅仅局限于 Generator
函数。async/await
无法取消,Generator
函数可以取消。async/await
无法获取函数执行的进度,Generator
函数可以获取函数执行的进度。async/await
错误处理不如 Promise
友好,Generator
函数可以捕获并处理错误。async/await
调试不如 Generator
函数友好,Generator
函数可以调试。async/await
无法在服务端使用,Generator
函数可以在服务端使用。async/await
和 Promise
的区别async/await
和 Promise
的区别主要有以下几点:
async/await
是 Promise
的语法糖。async/await
更简洁,更易读,内置执行器,更方便处理错误。async/await
适用于大多数异步操作,不仅仅局限于 Promise
。async/await
无法取消,Promise
可以取消。async/await
无法获取函数执行的进度,Promise
可以获取函数执行的进度。async/await
错误处理不如 Promise
友好,Promise
可以捕获并处理错误。async/await
调试不如 Promise
友好,Promise
可以调试。async/await
无法在服务端使用,Promise
可以在服务端使用。async/await
和 Generator
函数的选择一般来说,如果需要处理多个异步操作,建议使用 async/await
,因为它更简洁,更易读,而且内置执行器,更方便处理错误。
如果只需要处理单个异步操作,建议使用 Promise
,因为它提供了统一的 API
,各种异步操作都可以用同样的方法进行处理,并提供统一的接口。
如果需要处理多个异步操作,并且需要处理错误,建议使用 async/await
,因为它更简洁,更易读,而且内置执行器,更方便处理错误。
Promise
和 async/await
的选择一般来说,如果需要处理多个异步操作,建议使用 Promise
,因为它提供了统一的 API
,各种异步操作都可以用同样的方法进行处理,并提供统一的接口。
如果只需要处理单个异步操作,建议使用 async/await
,因为它更简洁,更易读,而且内置执行器,更方便处理错误。
如果需要处理多个异步操作,并且需要处理错误,建议使用 Promise
,因为它提供了统一的 API
,各种异步操作都可以用同样的方法进行处理,并提供统一的接口。