簡體   English   中英

在返回 function 的變量之前,如何等待 promise 完成?

[英]How do I wait for a promise to finish before returning the variable of a function?

我仍在為承諾而苦苦掙扎,但由於這里的社區,我取得了一些進展。

我有一個簡單的 JS function 查詢 Parse 數據庫。 它應該返回結果數組,但顯然由於查詢的異步性質(因此承諾),function 在結果之前返回,給我留下一個未定義的數組。

我需要做什么才能讓這個 function 等待 promise 的結果?

這是我的代碼:

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

}

而不是返回的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自己的博客文章中看到更多使用解析承諾的示例。

我需要做些什么來使這個函數等待承諾的結果?

使用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');
    }

您不希望使函數等待,因為JavaScript旨在是非阻塞的。 而是在函數結束時返回promise,然后調用函數可以使用promise來獲取服務器響應。

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

//Or return query.find(); 

你實際上並沒有在這里使用承諾。 Parse允許你使用回調或承諾; 你的選擇。

要使用promises,請執行以下操作:

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

我有同樣的問題,所以我維護了一些代碼,代碼需要調用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

...。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM