이번에는 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('next() called multiple times')) 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 중국어의 다른 관련 기사를 주목하세요. 웹사이트!
추천 도서:
위 내용은 비동기 및 대기 사용법에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!