JS异步代码
Posted 转角90
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JS异步代码相关的知识,希望对你有一定的参考价值。
Promise
const promise = new Promise((resolve,reject)=>
// 立即执行
// 成功返回resolve(),
// 失败返回reject()
)
promise.then(()=>
console.log(\'成功调用\')
).catch(()=>
console.log(\'失败调用\')
)
/*
resolve(promise)
如果resolve的值是Promise对象,那么当前的Promise的状态会由传入的Promise来决定
resolve(thenable)
resolve(
name:\'aa\',
then:function(resolve)
console.log(111)
)
*/
三个状态
- pending: 初始状态
- fulfilled:操作成功完成,执行resolve时,处于此状态,Promise已经被兑换
- rejected: 操作失败,执行了reject,Promise被拒绝
一旦状态改变,将是不可逆的。
方法
- then:
- 返回一个Promise
- return undefined,,
- catch:
- 执行时机,reject() / throw new Error(\'xxx\')
- finally
/*
类方法then/catch
*/
let studentList = []
let promise = Promise.resolve(studentList) // 相当于 new Promise() 并且执行resolve
promise.then((res)=>
console.log(res)
)
all
/*
将多个Promise包裹在一起会形成一个新的Promise,当所有Promise 的状态都为fulfilled,新的Promise为fulfilled
当有一个Promise状态为reject时,新的Promise状态为reject,并且会将第一个reject的返回值作为参数
*/
let p1 = new Promise((resolve)=>
setTimeout(()=>
resolve(\'p1\')
,2000)
)
let p2 = new Promise((resolve)=>
setTimeout(()=>
resolve(\'p2\')
,1000)
)
let p3 = new Promise((resolve)=>
setTimeout(()=>
resolve(\'p3\')
,5000)
)
// 会在5s后返回结果
Promise.all([p1,p2,p3]).then((res)=>
console.log(res) // [\'p1\', \'p2\', \'p3\']
)
let p4 = new Promise((resolve,reject)=>
setTimeout(()=>
reject(\'p4\')
,5000)
)
let p5 = new Promise((resolve,reject)=>
setTimeout(()=>
reject(\'p5\')
,1000)
)
let p6= new Promise((resolve)=>
setTimeout(()=>
resolve(\'p6\')
,5000)
)
// 会在5s后返回结果
Promise.all([p4,p5,p6]).then((res)=>
console.log(res) //
).catch(err=>
console.log(\'err\',err)
)
allSettled(ES11)
// 获取所有结果在then方法中
let p4 = new Promise((resolve,reject)=>
setTimeout(()=>
reject(\'p4\')
,5000)
)
let p5 = new Promise((resolve,reject)=>
setTimeout(()=>
reject(\'p5\')
,1000)
)
let p6= new Promise((resolve)=>
setTimeout(()=>
resolve(\'p6\')
,5000)
)
// 会在5s后返回结果 所有结果都返回在then中
Promise.allSettled([p4,p5,p6]).then((res)=>
// [ status: \'rejected\', reason: \'p4\', status: \'rejected\', reason: \'p5\',status: \'fulfilled\',value: \'p5\']
console.log(res)
)
race
// 会等到一个Promise有结果,无论是成功或失败
let p4 = new Promise((resolve,reject)=>
setTimeout(()=>
resolve(\'p4\')
,5000)
)
let p5 = new Promise((resolve,reject)=>
setTimeout(()=>
reject(\'p5\')
,1000)
)
let p6= new Promise((resolve,reject)=>
setTimeout(()=>
reject(\'p6\')
,5000)
)
Promise.race([p4,p5,p6]).then(res=>
console.log(res)
).catch(err=>console.log(\'err\',err)) // err p5
any
// 会等到一个Promise有结果,必须是fulfilled
let p4 = new Promise((resolve,reject)=>
setTimeout(()=>
resolve(\'p4\')
,5000)
)
let p5 = new Promise((resolve,reject)=>
setTimeout(()=>
reject(\'p5\')
,1000)
)
let p6= new Promise((resolve,reject)=>
setTimeout(()=>
reject(\'p6\')
,5000)
)
Promise.any([p4,p5,p6]).then(res=>
console.log(res) // p4
).catch(err=>
// 内部创建的错误信息,表示所有Promise都没有fulfilled
)
迭代器
帮助我们对某个数据结构进行遍历的对象
必须有一个next方法:
- next
- done: boolean
- value:
const names = [1, 2, 3, 4]
function createInterator(arr)
let index = 0
return
next()
// done :boolean
// value: 具体值/undefined
if (index < names.length)
return done: false, value: arr[index++]
else
return done: true, value: undefined
let obj = createInterator(names)
console.log(obj.next())
console.log(obj.next())
console.log(obj.next())
console.log(obj.next())
console.log(obj.next())
/*
done: false, value: 1
done: false, value: 2
done: false, value: 3
done: false, value: 4
done: true, value: undefined
*/
迭代器对象
const infos =
names:[1, 2, 3, 4],
[Symbol.iterator]() // 必须使用 [Symbol.iterator]()
let index = 0
return
next()
if (names.length > index)
return done:true
else
return done:false,value:names[index++]
const interator = infos[Symbol.iterator]()
console.log(interator.next())
console.log(interator.next())
console.log(interator.next())
console.log(interator.next())
console.log(interator.next())
for(let item of infos)
console.log(item)
// 优化
const infos =
names:[1, 2, 3, 4],
[Symbol.iterator]() // 必须使用 [Symbol.iterator]()
let index = 0
let entries = Object.entries(this)
return
next()
if (index < entries.length )
return done:false,value:entries[index++]
else
return done:true
const interator = infos[Symbol.iterator]()
console.log(interator.next())
console.log(interator.next())
for(let item of infos)
let [key,value] = item
console.log(key,value)
// 实现Iterator接口的自定义数组
class MyArray
constructor(...args)
this.length = args.length
for (let i=0;i<args.length;i++)
this[i] = args[i]
// [Symbol.iterator]()
// let index = 0
// let that = this
// return
// next()
// return
// done:index < that.length,
// value:that[index++]
//
// ,
//
//
*[Symbol.iterator]() // 简写方式:生成器 + yield* 语法糖
yield* this
监听迭代中断
// return函数
class MyArray
constructor(...args)
this.length = args.length
for (let i=0;i<args.length;i++)
this[i] = args[i]
[Symbol.iterator]()
let index = 0
let that = this
return
next()
return
done:index < that.length,
value:that[index++]
,
return()
console.log(\'监听中断\')
return done:true
生成器
函数控制,使用。更加灵活的控制函数什么时候继续执行,暂停执行
- 在函数后加
*
- 通过
yield
控制函数执行流程 - 生成器函数返回一个生成器
function* foo()
console.log(1111)
let a = yield \'aaaa\'
console.log(a)
console.log(2222)
yield \'bbbb\'
console.log(333)
yield \'cccc\'
console.log(444)
return \'dddd\' // return之后done:true,value:undefined
yield \'gggg\'
console.log(6666)
let a = foo()
console.log(a.next()) // 执行第一个next函数时,运行的代码时console.log(1111) \'aaaa\',
console.log(a.next(88888))// 执行第二个next函数时,let a = 88888 console.log(a) console.log(2222) \'bbbb\'
// 提前中断 return
console.log(a.return(\'aadd\'))
// 抛出异常 throw
console.log(a.throw(\'aadd\'))
生成器代替迭代器
const names = [1, 2, 3, 4]
function* createArrayIterator(arr)
// for (let i = 0; i < arr.length; i++)
// yield arr[i]
//
yield* arr // 语法糖,arr是一个可迭代对象, yield*会对对象进行依次,迭代
let iterator = createArrayIterator(names)
console.log(iterator.next()) // value: 1, done: false
console.log(iterator.next()) // value: 2, done: false
console.log(iterator.next()) // value: 3, done: false
console.log(iterator.next()) // value: 4, done: false
console.log(iterator.next()) // value: undefined, done: true
处理异步
function requestData(url)
return new Promise((resolve,reject)=>
resolve(url)
)
function* getData()
let res1 = yield requestData(\'h\')
let res2 = yield requestData(res1+\'y\')
let res3 = yield requestData(res2+\'f\')
console.log(res3)
let res = getData()
res.next().value.then(res1=>
res.next(res1).value.then(res2=>
res.next(res2).value.then(res3=>
console.log(res3)
)
)
)
// 自动执行生成器函数
function execGenfn(fn)
const generator = fn()
function exec(res)
let result = generator.next(res)
if (result.done)
return
result.value.then(r=>exec(r))
exec()
async await
async function getData()
let res1 = await requestData(\'h\')
let res2 = await requestData(res1+\'y\')
let res3 = await requestData(res2+\'f\')
console.log(res3)
异步函数返回值
async function foo2()
// 1. 返回一个普通值
// return 123 // Promise.resolve(123)
// 2. 返回一个Promise
// return new Promise((resolve,reject)=>
// setTimeout(()=>
// resolve(33)
// ,1110)
// )
// 3. 返回一个thenable
return
then(resolve,reject)
resolve(33333)
foo2().then(res=>console.log(res))
异步函数中出现异常,会被Promise.reject()捕获
异常处理
function requestData(url)
return new Promise((resolve,reject)=>
reject(url)
)
async function getData()
try
const a = await requestData(\'ddd\')
catch(error)
console.log(\'捕获异常代码:\',error)
以上是关于JS异步代码的主要内容,如果未能解决你的问题,请参考以下文章
script标签的async属性是用来异步加载,异步加载的作用是否同时下载,执行html代码和js代码
script标签的async属性是用来异步加载,异步加载的作用是否同时下载,执行html代码和js代码
Node.js插件编写-异步AsyncWorker的代码实现