web-dev-qa-db-ja.com

関数の変数を返す前に約束が終わるのを待つにはどうすればいいですか?

私はまだ約束に苦しんでいますが、ここのコミュニティのおかげでいくらか進歩しています。

私は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");
               }
    });                           

}
111
mac_55

resultsArrayを返す代わりに、結果配列のpromiseを返してから、呼び出しサイトでthenを返す - これは、関数が非同期I/Oを実行していることを呼び出し元に知らせるという追加の利点があります。 JavaScriptでの同時実行性のコーディングはそれに基づいています - より広い考えを得るために this question を読むことをお勧めします。

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自身のブログ投稿 で、クエリでparse promiseを使用する例をもっと見ることができます。

52

この関数に約束の結果を待たせるためにはどうすればいいですか。

async/awaitを使用します(ECMA6の一部ではありませんが、2017年末からChrome、Edge、Firefox、およびSafariで使用可能です。 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');
    }
10
Martin Meeser

JavaScriptは非ブロック化を目的としているため、関数を待機させたくはありません。その代わりに、関数の終わりに約束を返すのであれば、呼び出し側の関数はその約束を使用してサーバーの応答を取得できます。

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

//Or return query.find(); 
3
Trace

ここでは実際には約束を使用していません。 Parseではコールバックや約束を使うことができます。あなたの選択。

約束を使用するには、次の手順に従います。

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

これで、promiseが完了した後にものを実行するために、then()呼び出しの中のpromiseコールバックの中でそれを実行することができます。これまでのところ、これは通常のコールバックとまったく同じです。

実際に約束をうまく利用するのは、次のようにそれらを結び付けるときです。

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");
});
2
mash

私は同じ問題を抱えているので、私はいくつかのコードを管理しています、コードは別のタスクを処理するためにajaxを呼び出す必要があります、ここで私のコード

this.bindChangeEvent = function () {
    //select all bind change
    this._select_all.bind('change', function () {
        console.log('All')
        if ($(this).is(":checked")) {
            ///todo: call ajax to get all ids
            var idsAllItem = pointer.getAllData();

            console.log(idsAllItem);
            console.log('Another todo');

Ajax関数

this.getAllData = function() {
    var promises = [];
    var def = new $.Deferred();
    return new Promise((resolve, reject) => {
        // AJAX request
        var url = '...';
        $.ajax({
            url: url,
            type: "get",
            async: true,
            data: {},
            dataType: "json",
            success: function (data) {
                console.log('Ajjax done');
                resolve(data)
            },
            error: function (err) {
                reject(err)
            }
        });
    })
};

そして私は結果を得ます

Another todo
Output
Ajax Done

…。

0
dungphanxuan