비동기 호출에서 응답을 반환하는 방법은 무엇입니까?
P粉668113768
P粉668113768 2023-08-23 12:49:32
0
2
560
<p>비동기 요청을 하는 <code>foo</code> 함수에서 응답/결과를 어떻게 반환하나요? </p> <p>콜백에서 값을 반환하고 그 결과를 함수 내의 로컬 변수에 할당하고 해당 변수를 반환하려고 시도했지만 실제로 응답을 반환하는 메서드는 없습니다. 모두 <code>정의되지 않은< /code> 또는 변수 <code>result</code>의 초기 값입니다. </code></p><code> <p><strong>콜백을 허용하는 비동기 함수의 예</strong>(jQuery의 <code>ajax</code> 함수 사용): </p> <pre class="brush:php;toolbar:false;">function foo() { var 결과; $.아약스({ URL: '...', 성공: 함수(응답) { 결과 = 응답; // return response; // <- 그것도 시도해 봤습니다. } }); return result; // 항상 '정의되지 않음'을 반환합니다. }</pre> <p><strong>Node.js를 사용한 예:</strong></p> <pre class="brush:php;toolbar:false;">function foo() { var 결과; fs.readFile("경로/대상/파일", function(err, data) { 결과 = 데이터; // return data; // <- 그것도 시도해 봤습니다. }); return result; // 항상 '정의되지 않음'을 반환합니다. }</pre> <p><strong>Promise를 사용한 <code>then</code> 블록의 예: </strong></p> <pre class="brush:php;toolbar:false;">function foo() { var 결과; fetch(url).then(함수(응답)) { 결과 = 응답; // return response; // <- 그것도 시도해 봤습니다. }); return result; // 항상 '정의되지 않음'을 반환합니다. }</pre> <p><br /></p></code>
P粉668113768
P粉668113768

모든 응답(2)
P粉334721359

코드에 jQuery를 사용하지 않는다면 이 답변이 도움이 될 것입니다

코드는 다음과 같아야 합니다:

으아아아

Felix Kling은 AJAX용 jQuery를 사용하는 사람들을 위한 답변을 훌륭하게 작성했지만, 저는 jQuery를 사용하지 않는 사람들을 위해 대안을 제공하기로 결정했습니다.

(

참고: 새로운 API인 Angular 또는 Promise를 사용하는 경우 아래에 다른 답변을 추가했습니다 fetch)


당신이 직면한 문제

다음은 다른 답변의 "질문 설명"에 대한 간략한 요약입니다. 이 내용을 읽은 후 확실하지 않은 경우 해당 답변을 읽어보시기 바랍니다.

AJAX의

Aasynchronous을 의미합니다. 이는 요청 전송(또는 응답 수신)이 일반적인 실행 흐름에서 제거됨을 의미합니다. 귀하의 예에서 .send code>는 즉시 반환되고 다음 문 return result;success 콜백으로 전달한 함수를 호출하기 전에 실행됩니다. .코드>. .send code> 立即返回,并且在调用您作为 success 回调传递的函数之前执行下一条语句 return result;

이것은 반환할 때 정의한 리스너가 아직 실행되지 않았음을 의미하며, 이는 반환한 값이 아직 정의되지 않았음을 의미합니다.

다음은 간단한 비유입니다.

으아아아

(바이올린)

때문에

. AJAX는 서버가 브라우저에 값이 무엇인지 알려주기 전에 값을 반환하는 방식으로 작동합니다. a=5 部分尚未执行,因此返回的 a 值为 undefined

이 문제에 대한 가능한 해결책은 계산이 완료된 후 프로그램에 무엇을 해야 하는지 알려주는 코드를

재활성적으로 작성하는 것입니다. 으아아아

이것을

CPS라고 합니다. 기본적으로 우리는 완료 시 수행할 작업을 전달하고 이벤트가 완료될 때 반응하는 방법(예: AJAX 호출 또는 이 경우 시간 초과)을 코드에 알려줍니다. getFive 사용법:

으아아아

화면에 "5"가 나타납니다.

(바이올린).

가능한 해결책

이 문제를 해결하는 방법에는 기본적으로 두 가지가 있습니다.

    AJAX 호출을 동기식으로 만듭니다(SJAX라고 합니다).
  1. 콜백과 제대로 작동하도록 코드를 리팩터링하세요.
1. 동기식 AJAX - 하지 마세요! !

동기식 AJAX의 경우

하지 마세요! Felix의 답변은 이것이 왜 나쁜 생각인지에 대한 몇 가지 설득력 있는 주장을 제시합니다. 전체적으로 서버가 응답을 반환하고 매우 나쁜 사용자 경험을 생성할 때까지 사용자의 브라우저를 정지시킵니다. 이유를 설명하는 MDN의 또 다른 짧은 요약은 다음과 같습니다.

이 작업을 해야 한다면 깃발을 전달할 수 있습니다. 구체적인 방법은 다음과 같습니다:

으아아아

2. 코드 재구성

함수가 콜백을 허용하도록 만드세요. 예제 코드에서는 foo 接受回调。我们将告诉代码当 foo가 완료되었을 때 가 어떻게 반응하는지 알 수 있습니다.

그래서:

으아아아

는 다음과 같이 됩니다:

으아아아

여기에서는 익명 함수를 전달하지만 기존 함수에 대한 참조도 쉽게 전달하여 다음과 같이 만들 수 있습니다.

으아아아

이러한 유형의 콜백 디자인을 수행하는 방법에 대한 자세한 내용은 Felix의 답변을 확인하세요.

이제 그에 따라 동작하도록 foo 자체를 정의해 보겠습니다

으아아아

(바이올린)

이제 AJAX가 성공적으로 완료되면 실행할 작업을 허용하는 foo 함수가 생겼습니다. 응답 상태가 200이 아닌지 확인하고 적절한 조치(실패 처리기 생성 등)를 수행하여 이 기능을 더욱 확장할 수 있습니다. 그것은 우리의 문제를 효과적으로 해결했습니다.

이 내용을 여전히 이해하는 데 어려움이 있다면 AJAX에서 MDN 시작 가이드를 읽어보세요.

P粉642920522

질문

AjaxAasynchronous을 의미합니다. 이는 요청 전송(또는 응답 수신)이 일반적인 실행 흐름에서 제거됨을 의미합니다. 귀하의 예에서는 $.ajax 立即返回,并且下一条语句 return result; 在您作为 success 함수가 호출되기 전에 콜백이 전달됩니다.

다음은 동기 스트림과 비동기 스트림의 차이를 더 명확하게 만드는 비유입니다.

동기화

친구에게 전화를 걸어 정보를 찾아달라고 부탁한다고 상상해 보세요. 시간이 좀 걸릴 수도 있지만 친구가 필요한 대답을 할 때까지 전화 옆에서 허공을 바라보며 기다립니다.

"일반" 코드가 포함된 함수를 호출할 때도 같은 일이 발생합니다.

으아악

하지만 findItem 可能需要很长时间才能执行,但 var item = findItem(); 이후의 모든 코드는 함수가 결과를 반환할 때까지 대기해야 합니다.

비동기

같은 이유로 친구에게 다시 전화를 겁니다. 하지만 이번에는 당신이 그에게 당신이 불안하다고 말하고 그는 당신의 휴대폰을 사용하여 당신에게 다시 전화해야 합니다. 전화를 끊고 집을 떠나 계획했던 일을 모두 수행합니다. 친구가 다시 전화하면 귀하는 그가 제공한 정보를 처리하는 것입니다.

Ajax 요청을 하면 바로 이런 일이 발생합니다.

으아악

응답을 기다리지 않고 즉시 실행을 계속하며 Ajax 호출 후 명령문을 실행합니다. 최종적으로 응답을 받으려면 응답을 받은 후 호출되는 함수인 콜백(알고 계시나요? 콜백?)을 제공해야 합니다. 이 호출 이후의 모든 문은 콜백이 호출되기 전에 실행됩니다.


솔루션

JavaScript의 비동기 특성을 수용하세요! 일부 비동기 작업은 동기 작업을 제공하지만("Ajax"와 마찬가지로) 일반적으로 사용이 권장되지 않으며 특히 브라우저 컨텍스트에서는 더욱 그렇습니다.

왜 나쁜가요?

JavaScript는 브라우저의 UI 스레드에서 실행되며 장기 실행 프로세스는 UI를 잠가서 응답하지 않게 만들 수 있습니다. 또한 JavaScript 실행 시간에는 상한이 있으며 브라우저는 사용자에게 실행을 계속할지 여부를 묻습니다.

이 모든 것은 매우 나쁜 사용자 경험으로 이어집니다. 사용자는 모든 것이 제대로 작동하는지 알 수 없습니다. 또한 인터넷 속도가 느린 사용자에게는 효과가 더욱 악화됩니다.

아래에서는 서로를 기반으로 하는 세 가지 솔루션을 제시합니다.

  • Promises with async/await (ES2017+, 트랜스파일러나 재생기를 사용하는 경우 이전 브라우저에서 작동)
  • 콜백(노드에서 인기 있음)
  • then() 的 Promise 사용(ES2015+, 많은 Promise 라이브러리 중 하나를 사용하는 경우 이전 브라우저에서 작동)

이 세 가지 기능은 현재 브라우저와 Node 7+에서 사용할 수 있습니다.


ES2017+: async/await 进行承诺

사용

ECMAScript 2017 릴리스에는 비동기 함수에 대한 구문 수준 지원이 도입되었습니다. asyncawait를 사용하면 "동기식 스타일"로 비동기적으로 작성할 수 있습니다. 코드는 여전히 비동기식이지만 읽기/이해하기가 더 쉽습니다.

async/await 构建在 Promise 之上:async 函数始终返回 Promise。 await Promise 기반:

async 함수는 항상 Promise를 반환합니다.

await는 Promise를 "잠금 해제"하고 Promise가 해결하는 값을 생성하거나 Promise가 거부되면 오류를 발생시킵니다. async 函数或 JavaScript 模块。模块外部不支持顶级 await,因此您可能必须创建异步 IIFE (立即调用函数表达式)来启动异步중요

:

async 함수 또는 await만 사용할 수 있습니다. 가이드/모듈" rel="noreferrer">JavaScript 모듈. 최상위 await는 모듈 외부에서 지원되지 않으므로 비동기 IIFE(즉시 호출되는 함수 표현식 )을 사용하여 async 컨텍스트를 시작합니다(모듈을 사용하지 않는 경우).

async

findItem()await

에 대해 읽어보세요. 다음은 위의 delayed 함수 async/awaitfindItem()을 자세히 설명하는 예입니다. 으아아아 현재 browser

node
버전은

를 지원합니다. Regenerator

(또는 재생성을 사용하는 도구)를 사용하여 코드를 ES5로 변환하여

Babel

과 같은 이전 환경을 지원할 수도 있습니다. 🎜 🎜 🎜함수가 콜백을 받아들이도록 하세요🎜🎜 🎜콜백은 함수 1이 함수 2로 전달되는 경우입니다. 함수 2는 준비되면 함수 1을 호출할 수 있습니다. 비동기 프로세스의 컨텍스트에서는 비동기 프로세스가 완료될 때마다 콜백이 호출됩니다. 일반적으로 결과는 콜백에 전달됩니다. 🎜

질문의 예에서는 foo 接受回调并将其用作 success콜백을 만들 수 있습니다. 그래서 이건

으아아아

이 되었습니다 으아아아

여기에서는 "인라인" 함수를 정의하지만 모든 함수 참조를 전달할 수 있습니다.

으아아아

foo 자체는 다음과 같이 정의됩니다.

으아아아

콜백은 호출할 때 callback 将引用我们调用时传递给 foo 的函数,并将其传递给 success。 IE。一旦Ajax请求成功,$.ajax将调用callback并将响应传递给回调(可以用result에 전달한 함수를 참조하여 성공에 전달합니다. 즉. Ajax 요청이 성공하면 $.ajaxcallback을 호출하고 응답을 콜백에 전달합니다(result에서 참조할 수 있음). 이것이 우리가 콜백을 정의하는 방법입니다.)

콜백에 전달하기 전에 응답을 처리할 수도 있습니다.

으아아아

콜백을 사용하여 코드를 작성하는 것은 보기보다 쉽습니다. 결국 브라우저의 JavaScript는 주로 이벤트 중심(DOM 이벤트)입니다. Ajax 응답을 수신하는 것은 이벤트에 지나지 않습니다. 타사 코드를 사용해야 할 경우 어려움이 발생할 수 있지만 대부분의 문제는 애플리케이션 흐름만 생각하면 해결됩니다.


ES2015+: then()的 Promise >

을 사용하여

Promise API는 새로운 ECMAScript 6(ES2015) 기능이지만 이미 우수한 브라우저 지원을 갖추고 있습니다. 표준 Promises API를 구현하고 비동기 함수의 사용 및 구성을 단순화하기 위한 추가 메서드를 제공하는 많은 라이브러리도 있습니다(예: Bluebird).

약속은 미래가치의 그릇입니다. Promise가 값을 수신하거나(resolved) 취소되면(rejected) 해당 값에 액세스하려는 모든 "리스너"에게 알립니다.

일반 콜백에 비해 장점은 코드를 분리할 수 있고 작성하기가 더 쉽다는 것입니다.

Promise 사용 예시:

으아아아 으아아아
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿
회사 소개 부인 성명 Sitemap
PHP 중국어 웹사이트:공공복지 온라인 PHP 교육,PHP 학습자의 빠른 성장을 도와주세요!