함수의 변수를 반환하기 전에 약속이 완료되기를 기다리는 방법은 무엇입니까?


149

나는 여전히 약속으로 어려움을 겪고 있지만 여기의 커뮤니티 덕분에 진전이 있습니다.

Parse 데이터베이스를 쿼리하는 간단한 JS 함수가 있습니다. 결과 배열을 반환해야하지만 쿼리의 비동기 특성 (따라서 약속)으로 인해 함수가 결과보다 먼저 반환되어 정의되지 않은 배열을 남겨 둡니다.

이 함수가 약속의 결과를 기다리게하려면 어떻게해야합니까?

내 코드는 다음과 같습니다.

function resultsByName(name)
{   
    var Card = Parse.Object.extend("Card");
    var query = new Parse.Query(Card);
    query.equalTo("name", name.toString());

    var resultsArray = [];

    var promise = query.find({
               success: function(results) {
               // results is an array of Parse.Object.
                             console.log(results);
                             //resultsArray = results;
                             return results;
               },

               error: function(error) {
               // error is an instance of Parse.Error.
                             console.log("Error");
               }
    });                           

}

3
async / await 사용을 고려할 수도 있습니다. 노드는 이제 지원 비동기 / 기다리고 상자의 이후 버전 7.6
Viliam 시므 코

답변:


66

a resultsArray를 반환하는 대신 결과 배열에 대한 약속을 반환 한 다음 then호출 사이트 에서 약속을 반환 하면 호출자가 함수가 비동기 I / O를 수행한다는 것을 알 수 있습니다. JavaScript의 동시성 코딩은이를 기반으로합니다 . 더 넓은 아이디어를 얻으려면 이 질문 을 읽으십시오 .

function resultsByName(name)
{   
    var Card = Parse.Object.extend("Card");
    var query = new Parse.Query(Card);
    query.equalTo("name", name.toString());

    var resultsArray = [];

    return query.find({});                           

}

// later
resultsByName("Some Name").then(function(results){
    // access results here by chaining to the returned promise
});

Parse의 자체 블로그 게시물 에서 쿼리와 함께 구문 분석 약속을 사용하는 더 많은 예를 볼 수 있습니다 .


이것에 대한 지원이 무엇인지 말해 줄 수 있습니까? IE9가 이것을 지원합니까?
sandrina-p

예, 그러나 파싱 자체는 대부분 죽었으므로 @SandrinaPereira가 있습니다. 이것은 구문 분석 클라우드 코드입니다.
Benjamin Gruenbaum

1
아 그래서 이것은 순수한 자바 스크립트뿐만 아니라? 이 작업을 수행 할 수있는 방법을 찾고 있었지만 (다른 기능이 시작될 때까지 기다릴 수 있음) 순수한 자바 스크립트 만 사용되었습니다.
sandrina-p

문제는 약속이 아닌 코드 구문 분석에 관한 것입니다. 약속은 모든 브라우저에서 (라이브러리와 함께) 작동 할 수 있습니다. IE6에서 블루 버드 실행 및 Netscape 7
벤자민 Gruenbaum

1
나는 이틀 동안 SO를 읽었지만 여전히 아무도 이것을 해결하지 못했습니다. 이 답변은 서로 동일합니다. 이 함수는 OP가 요청한 값이 아닌 Promise를 반환합니다. 이 답변이 수락 된 것으로 표시되는 이유는 무엇입니까?
iGanja

19

이 함수가 약속의 결과를 기다리게하려면 어떻게해야합니까?

사용 async/await(ECMA6의 일부지만, 크롬, 에지, 파이어 폭스와 2017의 말부터 사파리에 해당하는, 참조 canIuse )
MDN

    async function waitForPromise() {
        // let result = await any Promise, like:
        let result = await Promise.resolve('this is a sample promise');
    }

주석으로 인해 추가됨 : 비동기 함수는 항상 Promise를 반환하며 TypeScript에서는 다음과 같습니다.

    async function waitForPromise(): Promise<string> {
        // let result = await any Promise, like:
        let result = await Promise.resolve('this is a sample promise');
    }

4
async 함수는 await없이 (또는 비동기 코드가 아닌) 호출 되어도 promise 객체를 반환합니다. 확실하지 않은 경우 console.log (waitForPromise ())의 결과를 확인하십시오. async 함수 내에서 console.log (result)를 확인 하면 예상 한 내용 인쇄되지만 async 함수에서 리턴하면 즉시 차단되지 않고 약속이 리턴됩니다. 자바 스크립트에서 차단하는 것은 단일 스레드 응용 프로그램이므로 일반적으로 매우 나쁩니다. 차단하면 다른 모든 펍 / 서브 클라이언트에 알림이 굶주리게되어 전체 앱이 무릎을 꿇게됩니다.
SRM

1
.net은 태스크 클래스와 같은 "약속"에 .wait ()를 가지고 있습니다. Javascript에이 기능이 누락 되었습니까? 출력을 다른 도구로 파이프 할 수있는 노드 명령 행 도구를 종료하기 전에 무언가를 기다려야합니다. "await"는 비동기 함수 내에서만 작동합니다. 약속의 범위 밖에서는 작동하지 않음을 의미합니다.
TamusJRoyce

@SRM 귀하의 의견은 샘플의 잘못된 해석에 기초한 것 같습니다. "내부"Promise.resolve (가장 간단한 Promise 예)에 관한 것이므로 귀하의 의견에 명시된 외부 발신자가 없습니다. 그래서 대답을 업데이트하기로 결정했습니다.
Martin Meeser

@TamusJRoyce 그 자체로 질문이지만 C #에서는 Task.ContinueWith (Task)를 사용할 수 있다고 생각합니다.이 답변은 허용 된 답변 ( "then ()")에서 볼 수있는 것과 같습니다.
Martin Meeser

나는 지금 본 것 같아요. 하나의 거대한 비동기 함수로 전체 스크립트를 거의 래핑 할 수 있습니다. 그리고 그 함수를 내 스크립트의 마지막 줄로 호출하십시오. 이 기능은 여전히 ​​약간의 보일러 플레이트입니다. 그러나 이전에 인식했던 것보다 훨씬 적습니다. 함수 내에서 함수를 작성하는 데 익숙하지 않습니다. @MartinMeeser 감사합니다!
TamusJRoyce

3

JavaScript는 비 블로킹을 목적으로하기 때문에 함수를 기다리지 않으려 고합니다. 대신 함수의 끝에서 약속을 반환하면 호출 함수는 약속을 사용하여 서버 응답을 얻을 수 있습니다.

var promise = query.find(); 
return promise; 

//Or return query.find(); 

1
success:비트가 있는 모든 콜백 항목 이 꺼져 있습니다.
Benjamin Gruenbaum

또는 더 나은 : return query.find();.
매시

또한 괜찮습니다. 나는 설명을 위해 이것을 그대로두고 주석으로 추가했습니다.
추적

나는 이것을 시도했지만 결과는 정의되지 않은 것 같습니다. resultsByName ( "name"). then (function (results) {console.log ( "배열"+ results.count);});
mac_55

1
고맙게도 결과 함수 내부에 일종의 오류가 있었을 것입니다. 지금 작동하고 있습니다. console.log를 results.length로 변경하고 반환 된 배열에 1 개의 항목이 있음을 알 수 있습니다. :)
mac_55

2

실제로 약속을 사용하고 있지 않습니다. 구문 분석을 통해 콜백 또는 약속을 사용할 수 있습니다. 당신의 선택.

약속을 사용하려면 다음을 수행하십시오.

query.find().then(function() {
    console.log("success!");
}, function() {
    console.log("error");
});

이제 약속이 완료된 후 물건을 실행하려면 then()통화 안의 약속 콜백 안에서만 실행할 수 있습니다 . 지금까지 이것은 일반 콜백과 정확히 동일합니다.

실제로 약속을 잘 활용하려면 다음과 같이 약속을 묶는 것입니다.

query.find().then(function() {
    console.log("success!");

    return new Parse.Query(Obj).get("sOmE_oBjEcT");
}, function() {
    console.log("error");
}).then(function() {
    console.log("success on second callback!");
}, function() {
    console.log("error on second callback");
});

결과 객체는 어떤 유형의 객체입니까? 배열을 포함하지 않는 것 같습니다
mac_55

의 배열이어야합니다 Parse.Object.
매시
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.