异步
(一)同步与异步的区别
同步:代码立刻执行,拿到结果才走。
- 举例说明:蒸好米饭再炒菜
异步:不能直接拿到结果,代码会继续向下执行
- 蒸米饭的时候就炒菜。
(二)JS中典型的异步例子
- setTimeout
- AJAX
- AddEventListener
如果一个函数的结果处于上述东西的内部,那么这个函数就是异步函数。
举例说明:
function RDM(){
setTimeout(()=>{
return Math.random()
})
}
分析:
- RDM没有写return 所以return undefined
- 箭头函数里的return才是RDM真正的结果
- 我们无法拿到setTimeout里真正的结果,该怎么办呢?
回调
(一)定义
回调的实质是一个函数。
写给自己调用的函数,不是回调;
写给别人调用的函数,才是回调。
(二)举例:
应用回调的方法,拿到RDM函数中setTimeout里的结果
//f1就是回调函数,我并没有调用,而是给RDM调用
function fn(x){ console.log(x) }
function RDM(fn){
setTimeout(()=>{
fn( Math.random() )
})
}
RDM(fn)
回调函数的简化
上面的例子可以简化成这种写法:
function RDM(fn){
setTimeout(()=>{
fn( Math.random() )
})
}
//简化后的方式
//RDM(x=>{
// console.log(x)
// })
//更加简化的方式
RDM(console.log)
- 适用范围:回调函数接收的参数个数 和回调函数中调用的函数的参数个数相等。
(x,y)=> { console.log(x) }
就无法使用上述的简化方式
小总结
- 异步任务无法立刻拿到结果
- 于是我们给异步任务传入一个回调函数
- 异步任务完成时会调用回调函数
- 调用回调函数时会把异步任务的结果,当作参数传入回调函数
Promise
(一)定义:
- Promise 是异步编程的一种解决方案
- 所谓
Promise
,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。Promise 提供统一的 API,各种异步操作都可以用同样的方法进行处理。
(二)基本应用
- return new Promise((resolve,reject)=>{})
- 任务成功调用resolve(value),失败调用reject(error).
(注:resolve
和reject
。它们是两个函数,由 JavaScript 引擎提供,不用自己部署。) resolve
函数的作用是,将Promise
对象的状态从“未完成”变为“成功”,在异步操作成功时调用,并将异步操作的结果value,作为参数传递出去;reject
函数的作用是,将Promise
对象的状态从“未完成”变为“失败”,在异步操作失败时调用,并将异步操作报出的错误error,作为参数传递出去。- 通过
.then((value)=>{},(error)=>{})
使用成功函数和失败函数,对promise对象中传出的value,error值进行处理。
注意:resolve和reject传出的参数都是唯一的,多值传参需要使用对象或者数组的形式。
- 如果在
then
中 使用了return
,那么return
的值会被Promise.resolve()
包装(返回一个新的promise)后续可以继续使用.then()
(三)应用实例
function timeout(ms) {
return new Promise((resolve, reject) => {
setTimeout(resolve('done'), ms);
});
}
timeout(100).then((value) => {
console.log(value);
});
//done
- 上面代码中,
timeout
方法返回一个Promise
实例。 - 过了指定的时间(
ms
参数)以后,Promise
实例的状态变为成功,resolve函数将参数'done'
传递出去,触发then
方法绑定的回调函数。
(四)其他API
Promise.all(
iterable
)- 方法返回一个
Promise
实例,此实例在 迭代器iterable
内所有的promise
都“resolved
”或参数中不包含promise
时回调完成(resolve
); 如果参数中
promise
有一个失败(rejected
),此实例回调失败(reject
),失败原因的是第一个失败promise
的结果。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););
- 方法返回一个
Promise.race(
iterable
)方法返回一个
promise
,一旦迭代器iterable
中的某个promise
解决或拒绝,返回的promise
就会解决或拒绝。Promise.race([promise1,promise2]) .then(value=>console.log(value));
Promise.catch(()=>{..})
- 在一个promise对象处于rejected后可以调用catch方法,接受reject传递的参数,并执行一个回调函数
Promise.allSettled
const promise1 = Promise.resolve(3); const promise2 = 42; const promise3 = new Promise((resolve, reject) => { setTimeout(resolve, 100, 'foo'); }); Promise.allSettled(promises).then((results) =>console.log(results)); // [Object { status: "fulfilled", value: 3 }, Object { status: "rejected", reason: "foo" }]
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。