目录
1. 早期异步代码困境
1.1 大聪明做法
2.2 早期正确做法
2. Promise
2.1 Executor立即执行
2.2 requestData 重构
2.3 promise的状态
2.4 resolve不同值的区别
2.5 Promise的实例方法
2.5.1 then方法
2.5.1.1 then的参数
2.5.1.2 then的多次调用
2.5.1.3 then的返回值
2.5.1.3.1 返回一个普通值 状态:fulfilled
2.5.1.3.2 明确返回一个promise 状态:fulfilled
2.5.1.3.3 返回一个thenable对象 状态:fulfilled
2.5.2 catch方法
2.5.2.1 catch的多次调用
2.5.2.2 catch的返回值
2.5.2.2.1 返回一个普通对象
2.5.2.2.2 明确返回一个promise
2.5.2.2.3 返回thenble对象
2.5.3 finally方法
2.6 Promise中的类方法/静态方法
2.6.1 Promise.reslove
2.6.2 Promise.reject
2.6.3 Promise.all
2.6.4 Promise.allSettled
2.6.5 Promise.race
2.6.6 Promise.any
3. Promise的回调地狱 (进阶)
3.1 卧龙解法
3.2 凤雏解法
3.3 生成器+Promise解法
3.4 自动化执行函数封装
3.5 最终解决回调地狱的办法
4. async/await 剖析
4.1 async内部代码同步执行
4.2 异步函数的返回值
4.3 异步函数的异常处理
4.4 await 关键字
5. 结语
首页 头条 一文搞懂promise/async await,赶超70%+的前端人

一文搞懂promise/async await,赶超70%+的前端人

Sep 28, 2022 am 10:39 AM
javascript promise async await

今天给大家分享promise,笔者将从早期的异步代码的困境、promise出现解决了什么问题、异步回调地狱的终极方案并且实现async await的核心语法,其实async/await只是generator+promise的一个变种而已。

1. 早期异步代码困境

  • 众所周知,js是单线程的,耗时操作都是交给浏览器来处理,等时间到了从队列中取出执行,设计到事件循环的概念,笔者也分享过,可以看以下,理解了可以更好的理解promise
  • 我以一个需求为切入点,我模拟网络请求(异步操作)
    • 如果网络请求成功了,你告知我成功了
    • 如果网络请求失败了,你告知我失败了

1.1 大聪明做法

function requestData(url) {
  setTimeout(() => {
    if (url === 'iceweb.io') {
      return '请求成功'
    }
    return '请求失败'
  }, 3000)
}

const result = requestData('iceweb.io')

console.log(result) //undefined
登录后复制
  • 首先你要理解js代码的执行顺序,而不是是想当然的,代码其实并不是按照你书写的顺序执行的。
  • 那么为什么是 undefined呢
    • 首先当我执行requestData函数,开始执行函数。遇到了异步操作不会阻塞后面代码执行的,因为js是单线程的,所以你写的return成功或者失败并没有返回,那我这个函数中,抛开异步操作,里面并没有返回值,所以值为undefined

2.2 早期正确做法

function requestData(url, successCB, failureCB) {
  setTimeout(() => {
    if (url === 'iceweb.io') {
      successCB('我成功了,把获取到的数据传出去', [{name:'ice', age:22}])
    } else {
      failureCB('url错误,请求失败')
    }
  }, 3000)
}

//3s后 回调successCB 
//我成功了,把获取到的数据传出去 [ { name: 'ice', age: 22 } ]
requestData('iceweb.io', (res, data) => console.log(res, data), rej => console.log(rej))

//3s后回调failureCB
//url错误,请求失败
requestData('icexxx.io', res => console.log(res) ,rej => console.log(rej))
登录后复制
  • 早期解决方案都是传入两个回调,一个失败的,一个成功的。那很多开发者会问这不是挺好的吗?挺简单的,js中函数是一等公民,可以传来传去,但是这样太灵活了,没有规范。
  • 如果使用的是框架,还要阅读一下框架源码,正确失败的传实参的顺序,如果传参顺序错误这样是非常危险的。

2. Promise

  • Promise(承诺),给予调用者一个承诺,过一会返回数据给你,就可以创建一个promise对象
  • 当我们new一个promise,此时我们需要传递一个回调函数,这个函数为立即执行的,称之为(executor)
  • 这个回调函数,我们需要传入两个参数回调函数,reslove,reject(函数可以进行传参)
    • 当执行了reslove函数,会回调promise对象的.then函数
    • 当执行了reject函数,会回调promise对象的.catche函数

2.1 Executor立即执行

new Promise((resolve, reject) => {
  console.log(`executor 立即执行`)
})
登录后复制
  • 传入的executor是立即执行的

2.2 requestData 重构

function requestData(url) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      if (url === 'iceweb.io') {
        //只能传递一个参数
        resolve('我成功了,把获取到的数据传出去')
      } else {
        reject('url错误,请求失败')
      }
    }, 3000)    
  })
}

//1. 请求成功
requestData('iceweb.io').then(res => {
  //我成功了,把获取到的数据传出去
  console.log(res)
})

//2. 请求失败

//2.2 第一种写法
//url错误,请求失败
requestData('iceweb.org').then(res => {},rej => console.log(rej))

//2.2 第二种写法
//url错误,请求失败
requestData('iceweb.org').catch(e => console.log(e))
登录后复制
  • 在函数中,new这个类的时候,传入的回调函数称之为executor(会被Promise类中自动执行)
  • 在正确的时候调用resolve函数,失败的时候调用reject函数,把需要的参数传递出去。
  • 异常处理
    • 其中在.then方法中可以传入两个回调,您也可以查看Promise/A+规范
      • 第一个则是fulfilled的回调
      • 第二个则是rejected的回调
  • 那这样有什么好处呢? 看起来比早期处理的方案还要繁琐呢?
    • 统一规范,可以增强阅读性和扩展性

    • 小幅度减少回调地狱

2.3 promise的状态

  • 首先先给大家举个栗子,把代码抽象为现实的栗子
    • 你答应你女朋友,下周末带她去吃好吃的 (还未到下周末,此时状态为待定状态)
    • 时间飞快,今天就是周末了,你和你女友一起吃了烤肉、甜点、奶茶...(已兑现状态
    • 时间飞快,今天就是周末了,正打算出门。不巧产品经理,因为线上出现的紧急问题,需要回公司解决一下,你(为了生活)只能委婉的拒绝一下女友,并且说明一下缘由(已拒绝状态)
  • 使用promise的时候,给它一个承诺,我们可以将他划分为三个阶段
    • pending(待定),执行了executor,状态还在等待中,没有被兑现,也没有被拒绝
    • fulfilled(已兑现),执行了resolve函数则代表了已兑现状态
    • rejected(已拒绝),执行了reject函数则代表了已拒绝状态
  • 首先,状态只要从待定状态,变为其他状态,则状态不能再改变

思考以下代码:

const promise = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject('失败')
    resolve('成功')
  }, 3000);
})

promise.then(res => console.log(res)).catch(err => console.log(err))

//失败
登录后复制
  • 当我调用reject之后,在调用resolve是无效的,因为状态已经发生改变,并且是不可逆的。

2.4 resolve不同值的区别

  • 如果resolve传入一个普通的值或者对象,只能传递接受一个参数,那么这个值会作为then回调的参数
const promise = new Promise((resolve, reject) => {
  resolve({name: 'ice', age: 22})
})

promise.then(res => console.log(res))

// {name: 'ice', age: 22}
登录后复制
  • 如果resolve中传入的是另外一个Promise,那么这个新Promise会决定原Promise的状态
const promise = new Promise((resolve, reject) => {
  resolve(new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve('ice')
    }, 3000);
  }))
})

promise.then(res => console.log(res))

//3s后 ice
登录后复制
  • 如果resolve中传入的是一个对象,并且这个对象有实现then方法,那么会执行该then方法,then方法会传入resolvereject函数。此时的promise状态取决于你调用了resolve,还是reject函数。这种模式也称之为: thenable
const promise = new Promise((resolve, reject) => {
  resolve({
    then(res, rej) {
      res('hi ice')
    }
  })
})

promise.then(res => console.log(res))

// hi ice
登录后复制

2.5 Promise的实例方法

  • 实例方法,存放在Promise.prototype上的方法,也就是Promise的显示原型上,当我new Promise的时候,会把返回的改对象的 promise[[prototype]](隐式原型) === Promise.prototype (显示原型)
  • 即new返回的对象的隐式原型指向了Promise的显示原型

2.5.1 then方法

2.5.1.1 then的参数
  • then方法可以接受参数,一个参数为成功的回调,另一个参数为失败的回调,前面重构requestData中有演练过。
const promise = new Promise((resolve, reject) => {
  resolve('request success')
  // reject('request error')
})

promise.then(res => console.log(res), rej => console.log(rej))

//request success
登录后复制
  • 如果只捕获错误,还可以这样写
    • 因为第二个参数是捕获异常的,第一个可以写个null""占位
const promise = new Promise((resolve, reject) => {
  // resolve('request success')
  reject('request error')
})

promise.then(null, rej => console.log(rej))

//request error
登录后复制
2.5.1.2 then的多次调用
const promise = new Promise((resolve, reject) => {
  resolve('hi ice')
})

promise.then(res => ({name:'ice', age:22}))
       .then(res => console.log(res))
       
//{name:'ice', age:22}
登录后复制
登录后复制
  • 调用多次则会执行多次
2.5.1.3 then的返回值
  • then方法是有返回值的,它的返回值是promise,但是是promise那它的状态如何决定呢?接下来让我们一探究竟。
2.5.1.3.1 返回一个普通值 状态:fulfilled
const promise = new Promise((resolve, reject) => {
  resolve('hi ice')
})

promise.then(res => ({name:'ice', age:22}))
       .then(res => console.log(res))
       
//{name:'ice', age:22}
登录后复制
登录后复制
  • 返回一个普通值,则相当于主动调用Promise.resolve,并且把返回值作为实参传递到then方法中。
  • 如果没有返回值,则相当于返回undefined
2.5.1.3.2 明确返回一个promise 状态:fulfilled
const promise = new Promise((resolve, reject) => {
  resolve('hi ice')
})

promise.then(res => {
  return new Promise((resolve, reject) => {
    resolve('then 的返回值')
  })
}).then(res => console.log(res))

//then 的返回值
登录后复制
  • 主动返回一个promise对象,状态和你调用resolve,还是reject有关
2.5.1.3.3 返回一个thenable对象 状态:fulfilled
const promise = new Promise((resolve, reject) => {
  resolve('hi ice')
})

promise.then(res => {
  return {
    then(resolve, reject) {
      resolve('hi webice')
    }
  }
}).then(res => console.log(res))

//hi webice
登录后复制
  • 返回了一个thenable对象,其状态取决于你是调用了resolve,还是reject

2.5.2 catch方法

2.5.2.1 catch的多次调用
const promise = new Promise((resolve, reject) => {
  reject('ice error')
})

promise.catch(err => console.log(err))
promise.catch(err => console.log(err))
promise.catch(err => console.log(err))

//ice error
//ice error
//ice error
登录后复制
2.5.2.2 catch的返回值
  • catch方法是有返回值的,它的返回值是promise,但是是promise那它的状态如何决定呢?接下来让我们一探究竟。
  • 如果返回值明确一个promise或者thenble对象,取决于你调用了resolve还是reject
2.5.2.2.1 返回一个普通对象
const promise = new Promise((resolve, reject) => {
  reject('ice error')
})

promise.catch(err => ({name:'ice', age: 22})).then(res => console.log(res))

//{name:'ice', age: 22}
登录后复制
2.5.2.2.2 明确返回一个promise
const promise = new Promise((resolve, reject) => {
  reject('ice error')
})

promise.catch(err => {
  return new Promise((resolve, reject) => {
    reject('ice error promise')
  })
}).catch(res => console.log(res))

//ice error promise
登录后复制
  • 此时new Promise() 调用了reject函数,则会被catch捕获到
2.5.2.2.3 返回thenble对象
const promise = new Promise((resolve, reject) => {
  reject('ice error')
})

promise.catch(err => {
  return {
    then(resolve, reject) {
      reject('ice error then')
    }
  }
}).catch(res => console.log(res))

//ice error then
登录后复制

2.5.3 finally方法

  • ES9(2018)新实例方法
  • finally(最后),无论promise状态是fulfilled还是rejected都会执行一次finally方法
const promise = new Promise((resolve, reject) => {
  resolve('hi ice')
})

promise.then(res => console.log(res)).finally(() => console.log('finally execute'))

//finally execute
登录后复制

2.6 Promise中的类方法/静态方法

2.6.1 Promise.reslove

Promise.resolve('ice')
//等价于
new Promise((resolve, reject) => resolve('ice'))
登录后复制
  • 有的时候,你已经预知了状态的结果为fulfilled,则可以用这种简写方式

2.6.2 Promise.reject

Promise.reject('ice error')
//等价于
new Promise((resolve, reject) => reject('ice error'))
登录后复制
  • 有的时候,你已经预知了状态的结果为rejected,则可以用这种简写方式

2.6.3 Promise.all

fulfilled 状态

const promise1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('hi ice')
  }, 1000);
})

const promise2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('hi panda')
  }, 2000);
})

const promise3 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('hi grizzly')
  }, 3000);
})


Promise.all([promise1, promise2, promise3]).then(res => console.log(res))

//[ 'hi ice', 'hi panda', 'hi grizzly' ]
登录后复制
  • all方法的参数传入为一个可迭代对象,返回一个promise,只有三个都为resolve状态的时候才会调用.then方法。
  • 只要有一个promise的状态为rejected,则会回调.catch方法

rejected状态

const promise1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('hi ice')
  }, 1000);
})

const promise2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject('hi panda')
  }, 2000);
})

const promise3 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('hi grizzly')
  }, 3000);
})

Promise.all([promise1, promise2, promise3]).then(res => console.log(res)).catch(err => console.log(err))

//hi panda
登录后复制
  • 当遇到rejectd的时候,后续的promise结果我们是获取不到,并且会把reject的实参,传递给catch的err形参中

2.6.4 Promise.allSettled

  • 上面的Promise.all有一个缺陷,就是当遇到一个rejected的状态,那么对于后面是resolve或者reject的结果我们是拿不到的
  • ES11 新增语法Promise.allSettled,无论状态是fulfilled/rejected都会把参数返回给我们

所有promise都有结果

const promise1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject('hi ice')
  }, 1000);
})

const promise2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('hi panda')
  }, 2000);
})

const promise3 = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject('hi grizzly')
  }, 3000);
})

Promise.allSettled([promise1, promise2, promise3]).then(res => console.log(res))

/* [
  { status: 'rejected', reason: 'hi ice' },
  { status: 'fulfilled', value: 'hi panda' },
  { status: 'rejected', reason: 'hi grizzly' }
] */
登录后复制
  • 该方法会在所有的Promise都有结果,无论是fulfilled,还是rejected,才会有最终的结果

其中一个promise没有结果

const promise1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject('hi ice')
  }, 1000);
})

const promise2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('hi panda')
  }, 2000);
})

const promise3 = new Promise((resolve, reject) => {})


Promise.allSettled([promise1, promise2, promise3]).then(res => console.log(res))
// 什么都不打印
登录后复制
  • 其中一个promise没有结果,则什么都结果都拿不到

2.6.5 Promise.race

  • race(竞争竞赛)
  • 优先获取第一个返回的结果,无论结果是fulfilled还是rejectd
const promise1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject('hi error')
  }, 1000);
})

const promise2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('hi panda')
  }, 2000);
})


Promise.race([promise1, promise2])
       .then(res => console.log(res))
       .catch(e => console.log(e))
       
//hi error
登录后复制

2.6.6 Promise.any

  • 与race类似,只获取第一个状态为fulfilled,如果全部为rejected则报错AggregateError
const promise1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject('hi error')
  }, 1000);
})

const promise2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('hi panda')
  }, 2000);
})


Promise.any([promise1, promise2])
       .then(res => console.log(res))
       .catch(e => console.log(e))
       
//hi panda
登录后复制

3. Promise的回调地狱 (进阶)

  • 我还是以一个需求作为切入点,把知识点嚼碎了,一点一点喂进你们嘴里。
    • 当我发送网络请求的时候,需要拿到这次网络请求的数据,再发送网络请求,就这样重复三次,才能拿到我最终的结果。

3.1 卧龙解法

function requestData(url) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      if (url.includes('iceweb')) {
        resolve(url)
      } else {
        reject('请求错误')
      }
    }, 1000);
  })
}


requestData('iceweb.io').then(res => {
  requestData(`iceweb.org ${res}`).then(res => {
    requestData(`iceweb.com ${res}`).then(res => {
      console.log(res)
    })
  })
})

//iceweb.com iceweb.org iceweb.io
登录后复制
  • 虽然能够实现,但是多层代码的嵌套,可读性非常差,我们把这种多层次代码嵌套称之为回调地狱

3.2 凤雏解法

function requestData(url) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      if (url.includes('iceweb')) {
        resolve(url)
      } else {
        reject('请求错误')
      }
    }, 1000);
  })
}

requestData('iceweb.io').then(res => {
  return requestData(`iceweb.org ${res}`)
}).then(res => {
  return requestData(`iceweb.com ${res}`)
}).then(res => {
  console.log(res)
})

//iceweb.com iceweb.org iceweb.io
登录后复制
  • 利用了then链式调用这一特性,返回了一个新的promise,但是不够优雅,思考一下能不能写成同步的方式呢?

3.3 生成器+Promise解法

function requestData(url) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      if (url.includes('iceweb')) {
        resolve(url)
      } else {
        reject('请求错误')
      }
    }, 1000);
  })
}

function* getData(url) {
  const res1 = yield requestData(url)
  const res2 = yield requestData(res1)
  const res3 = yield requestData(res2)

  console.log(res3)
}

const generator = getData('iceweb.io')

generator.next().value.then(res1 => {
  generator.next(`iceweb.org ${res1}`).value.then(res2 => {
    generator.next(`iceweb.com ${res2}`).value.then(res3 => {
      generator.next(res3)
    })
  })
})

//iceweb.com iceweb.org iceweb.io
登录后复制
  • 大家可以发现我们的getData已经变为同步的形式,可以拿到我最终的结果了。那么很多同学会问,generator一直调用.next不是也产生了回调地狱吗?
  • 其实不用关心这个,我们可以发现它这个是有规律的,我们可以封装成一个自动化执行的函数,我们就不用关心内部是如何调用的了。

3.4 自动化执行函数封装

function requestData(url) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      if (url.includes('iceweb')) {
        resolve(url)
      } else {
        reject('请求错误')
      }
    }, 1000);
  })
}

function* getData() {
  const res1 = yield requestData('iceweb.io')
  const res2 = yield requestData(`iceweb.org ${res1}`)
  const res3 = yield requestData(`iceweb.com ${res2}`)

  console.log(res3)
}

//自动化执行 async await相当于自动帮我们执行.next
function asyncAutomation(genFn) {
  const generator = genFn()

  const _automation = (result) => {
    let nextData = generator.next(result)
    if(nextData.done) return

    nextData.value.then(res => {
      _automation(res)
    })
  }

  _automation()
}

asyncAutomation(getData)

//iceweb.com iceweb.org iceweb.io
登录后复制
  • 利用promise+生成器的方式变相实现解决回调地狱问题,其实就是async await的一个变种而已
  • 最早为TJ实现,前端大神人物
  • async await核心代码就类似这些,内部主动帮我们调用.next方法

3.5 最终解决回调地狱的办法

function requestData(url) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      if (url.includes('iceweb')) {
        resolve(url)
      } else {
        reject('请求错误')
      }
    }, 1000);
  })
}

async function getData() {
  const res1 = await requestData('iceweb.io')
  const res2 = await requestData(`iceweb.org ${res1}`)
  const res3 = await requestData(`iceweb.com ${res2}`)

  console.log(res3)
}

getData()

//iceweb.com iceweb.org iceweb.io
登录后复制
  • 你会惊奇的发现,只要把getData生成器函数函数,改为async函数,yeild的关键字替换为await就可以实现异步代码同步写法了。

4. async/await 剖析

  • async(异步的)
  • async 用于申明一个异步函数

4.1 async内部代码同步执行

  • 异步函数的内部代码执行过程和普通的函数是一致的,默认情况下也是会被同步执行
async function sayHi() {
  console.log('hi ice')
}

sayHi()

//hi ice
登录后复制

4.2 异步函数的返回值

  • 异步函数的返回值和普通返回值有所区别

    • 普通函数主动返回什么就返回什么,不返回为undefined
    • 异步函数的返回值特点
      • 明确有返回一个普通值,相当于Promise.resolve(返回值)
      • 返回一个thenble对象则由,then方法中的resolve,或者reject有关
      • 明确返回一个promise,则由这个promise决定
  • 异步函数中可以使用await关键字,现在在全局也可以进行await,但是不推荐。会阻塞主进程的代码执行

4.3 异步函数的异常处理

  • 如果函数内部中途发生错误,可以通过try catch的方式捕获异常
  • 如果函数内部中途发生错误,也可以通过函数的返回值.catch进行捕获
async function sayHi() {
  console.log(res)
}
sayHi().catch(e => console.log(e))

//或者

async function sayHi() {
  try {
    console.log(res)
  }catch(e) {
    console.log(e)
  }
}

sayHi()

//ReferenceError: res is not defined
登录后复制

4.4 await 关键字

  • 异步函数中可以使用await关键字,普通函数不行
  • await特点
    • 通常await关键字后面都是跟一个Promise
      • 可以是普通值
      • 可以是thenble
      • 可以是Promise主动调用resolve或者reject
    • 这个promise状态变为fulfilled才会执行await后续的代码,所以await后面的代码,相当于包括在.then方法的回调中,如果状态变为rejected,你则需要在函数内部try catch,或者进行链式调用进行.catch操作
function requestData(url) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      if (url.includes('iceweb')) {
        resolve(url)
      } else {
        reject('请求错误')
      }
    }, 1000);
  })
}

async function getData() {
  const res = await requestData('iceweb.io')
  console.log(res)
}

getData()

// iceweb.io
登录后复制

5. 结语

  • 如果现在真的看不到未来是怎样,你就不如一直往前走,不知道什么时候天亮,去奔跑就好,跑着跑着天就亮了。

【相关推荐:javascript视频教程编程基础视频

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
1 个月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
1 个月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
1 个月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.聊天命令以及如何使用它们
1 个月前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

如何使用WebSocket和JavaScript实现在线语音识别系统 如何使用WebSocket和JavaScript实现在线语音识别系统 Dec 17, 2023 pm 02:54 PM

如何使用WebSocket和JavaScript实现在线语音识别系统引言:随着科技的不断发展,语音识别技术已经成为了人工智能领域的重要组成部分。而基于WebSocket和JavaScript实现的在线语音识别系统,具备了低延迟、实时性和跨平台的特点,成为了一种被广泛应用的解决方案。本文将介绍如何使用WebSocket和JavaScript来实现在线语音识别系

WebSocket与JavaScript:实现实时监控系统的关键技术 WebSocket与JavaScript:实现实时监控系统的关键技术 Dec 17, 2023 pm 05:30 PM

WebSocket与JavaScript:实现实时监控系统的关键技术引言:随着互联网技术的快速发展,实时监控系统在各个领域中得到了广泛的应用。而实现实时监控的关键技术之一就是WebSocket与JavaScript的结合使用。本文将介绍WebSocket与JavaScript在实时监控系统中的应用,并给出代码示例,详细解释其实现原理。一、WebSocket技

如何利用JavaScript和WebSocket实现实时在线点餐系统 如何利用JavaScript和WebSocket实现实时在线点餐系统 Dec 17, 2023 pm 12:09 PM

如何利用JavaScript和WebSocket实现实时在线点餐系统介绍:随着互联网的普及和技术的进步,越来越多的餐厅开始提供在线点餐服务。为了实现实时在线点餐系统,我们可以利用JavaScript和WebSocket技术。WebSocket是一种基于TCP协议的全双工通信协议,可以实现客户端与服务器的实时双向通信。在实时在线点餐系统中,当用户选择菜品并下单

如何使用WebSocket和JavaScript实现在线预约系统 如何使用WebSocket和JavaScript实现在线预约系统 Dec 17, 2023 am 09:39 AM

如何使用WebSocket和JavaScript实现在线预约系统在当今数字化的时代,越来越多的业务和服务都需要提供在线预约功能。而实现一个高效、实时的在线预约系统是至关重要的。本文将介绍如何使用WebSocket和JavaScript来实现一个在线预约系统,并提供具体的代码示例。一、什么是WebSocketWebSocket是一种在单个TCP连接上进行全双工

言出必行:兑现承诺的好处和坏处 言出必行:兑现承诺的好处和坏处 Feb 18, 2024 pm 08:06 PM

在日常生活中,我们常常会遇到承诺与兑现之间的问题。无论是在个人关系中,还是在商业交易中,承诺的兑现都是建立信任的关键。然而,承诺的利与弊也常常会引起争议。本文将探讨承诺的利与弊,并给出一些建议,如何做到言出必行。承诺的利是显而易见的。首先,承诺可以建立信任。当一个人信守承诺时,他会让别人相信自己是一个可信赖的人。信任是人与人之间建立起的纽带,它可以让人们更加

JavaScript和WebSocket:打造高效的实时天气预报系统 JavaScript和WebSocket:打造高效的实时天气预报系统 Dec 17, 2023 pm 05:13 PM

JavaScript和WebSocket:打造高效的实时天气预报系统引言:如今,天气预报的准确性对于日常生活以及决策制定具有重要意义。随着技术的发展,我们可以通过实时获取天气数据来提供更准确可靠的天气预报。在本文中,我们将学习如何使用JavaScript和WebSocket技术,来构建一个高效的实时天气预报系统。本文将通过具体的代码示例来展示实现的过程。We

简易JavaScript教程:获取HTTP状态码的方法 简易JavaScript教程:获取HTTP状态码的方法 Jan 05, 2024 pm 06:08 PM

JavaScript教程:如何获取HTTP状态码,需要具体代码示例前言:在Web开发中,经常会涉及到与服务器进行数据交互的场景。在与服务器进行通信时,我们经常需要获取返回的HTTP状态码来判断操作是否成功,根据不同的状态码来进行相应的处理。本篇文章将教你如何使用JavaScript获取HTTP状态码,并提供一些实用的代码示例。使用XMLHttpRequest

深入了解Promise.resolve() 深入了解Promise.resolve() Feb 18, 2024 pm 07:13 PM

Promise.resolve()详解,需要具体代码示例Promise是JavaScript中一种用于处理异步操作的机制。在实际开发中,经常需要处理一些需要按顺序执行的异步任务,而Promise.resolve()方法就是用来返回一个已经Fulfilled状态的Promise对象。Promise.resolve()是Promise类的一个静态方法,它接受一个