>  기사  >  웹 프론트엔드  >  비동기 및 대기 사용법에 대한 자세한 설명

비동기 및 대기 사용법에 대한 자세한 설명

php中世界最好的语言
php中世界最好的语言원래의
2018-03-23 15:16:365189검색

이번에는 async 및 wait 사용법에 대해 자세히 설명하겠습니다. async 및 wait 사용 시 주의사항은 무엇인가요?

Koa는 매우 유명한 Node 서버측 프레임워크로 1.x 버전과 2.x 버전으로 제공됩니다. 전자는 비동기 작업을 위해 생성기를 사용하고 후자는 최신 async/await 솔루션을 사용합니다

이 작성 방법을 처음 사용했을 때 문제가 발생했습니다. 코드는 다음과 같습니다.

const Koa = require('koa');
const app = new Koa();
const doSomething = time => {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve('task done!')
    }, time)
  })
}
// 用来打印请求信息
app.use((ctx, next) => {
  console.log(`${ctx.method}:::${ctx.url}`)
  next()
})
app.use(async ctx => {
  const result = await doSomething(3000)
  console.log(result);
  ctx.body = result
})
app.listen(3000);

테스트해 보겠습니다. 컬 http ://localhost:3000

예상 결과:

(3초 후...)작업 완료!

그러나 현실은:

(즉시)
Not Found

대체 뭐죠? 예상대로 작동하지 않는 이유는 무엇입니까? 이를 위해서는 Koa의 미들웨어가 어떻게 직렬로 연결되어 있는지 이해해야 합니다. 소스 코드를 살펴보면 미들웨어를 연결하는 코드는 다음과 같습니다.

function compose (middleware) {
 return function (context, next) {
  // 这个index用来计数,防止next被多次调用
  let index = -1
  // 执行入口
  return dispatch(0)
  
  function dispatch (i) {
   // 如果next被多次调用,报异常
   if (i <= index) return Promise.reject(new Error(&#39;next() called multiple times&#39;))
   index = i
   // 取出第一个middleware
   let fn = middleware[i]
   // 将最初传入的next作为最后一个函数执行
   if (i === middleware.length) fn = next
   if (!fn) return Promise.resolve()
   try {
    /**
    这里就是关键了,Promise.resolve是什么意思呢?
     Promise.resolve方法有下面三种形式:
     
     Promise.resolve(value);
     Promise.resolve(promise);
     Promise.resolve(theanable);
     
    这三种形式都会产生一个新的Promise。其中:
    第一种形式提供了自定义Promise的值的能力,它与Promise.reject(reason)对应。两者的不同,在于得到的Promise的状态不同。
    第二种形式,提供了创建一个Promise的副本的能力。
    第三种形式,是将一个类似Promise的对象转换成一个真正的Promise对象。它的一个重要作用是将一个其他实现的Promise对象封装成一个当前实现的Promise对象。例如你正在用bluebird,但是现在有一个Q的Promise,那么你可以通过此方法把Q的Promise变成一个bluebird的Promise。第二种形式可以归在第三种里面
    
    **/
    return Promise.resolve(fn(context, function next () {
     // 执行下一个middleware,返回结果也是一个Promise
     return dispatch(i + 1)
    }))
   } catch (err) {
    return Promise.reject(err)
   }
  }
 }
}

위의 내용을 바탕으로 이전 질문을 살펴보겠습니다. 왜 두 번째 미들웨어가 실행될 때까지 기다리지 않고 즉시 응답이 반환됩니까?

첫 번째 미들웨어는 비동기 기능이 아니기 때문이죠.

다음 메소드의 각 실행은 실제로 Promise 객체를 반환하므로 미들웨어에서 비동기 작업을 수행하고 완료를 기다리고 싶다면 미들웨어를 실행하기 전에 대기를 추가해야 합니다

그런 다음 이전 코드를 다시 작성해 보겠습니다

app.use(async (ctx, next) => {
  console.log(`${ctx.method}:::${ctx.url}`)
  await next()
})
app.use(async ctx => {
  const result = await doSomething(3000)
  console.log(result);
  ctx.body = result
})

좋아요, 문제 없습니다. 모든 것이 예상대로 실행됩니다. 박수:

오류 처리

Promise의 강력한 기능과 비동기/대기 구문의 도움으로 try/만 작성하면 됩니다. 가장 바깥쪽 미들웨어에서 작업을 포착하면 이후의 모든 미들웨어 예외를 포착할 수 있습니다!

app.use(async (ctx, next) => {
  try{
    await next()
  }catch(err){
    console.log(err)
  }
})
app.use(async (ctx)=>{
  throw new Error('something wrong!')
  ctx.body = 'Hello'
})

미들웨어 체인을 기반으로 모든 제어가 가능하며 Promise를 기반으로 하므로 모든 작업이 쉽게 작동됩니다. 더 이상 if (err) return next(err) 는 없지만 promise만 있습니다

이 기사의 사례를 읽은 후 방법을 마스터했다고 믿습니다. 더 흥미로운 정보를 보려면 PHP 중국어의 다른 관련 기사를 주목하세요. 웹사이트!

추천 도서:

날짜 선택기 사용 방법

mixin의 상위 구성 요소 사용에 대한 자세한 설명

Vue.js에서 ejsExcel 템플릿 사용

위 내용은 비동기 및 대기 사용법에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.