Как мне дождаться завершения обещания, прежде чем возвращать переменную функции?


Я все еще борюсь с обещаниями, но делаю некоторый прогресс благодаря сообществу здесь.

У меня есть простая функция JS, которая запрашивает базу данных Parse. Предполагается, что он возвращает массив результатов, но, очевидно, из-за асинхронного характера запроса (отсюда и обещания), функция возвращает перед результатами, оставляя меня с неопределенным массивом.

что мне нужно сделать, чтобы заставить эту функцию ждать результата обещаешь?

вот мой код:

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

}
4 82

4 ответа:

вместо возврата a resultsArray вы возвращаете обещание для массива результатов, а затем then что на сайте вызова - это имеет дополнительное преимущество вызывающего абонента, зная, что функция выполняет асинхронный ввод-вывод параллелизм кодирования в 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 promises с запросами в разбор собственного блога об этом.

что мне нужно сделать, чтобы заставить эту функцию ждать результата обещания?

использовать async/await (Не часть ECMA6, но доступно для Chrome, Edge, Firefox и Safari с конца 2017 года, см. canIuse)
MDN

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

в качестве примечания: C# имеет это в течение нескольких лет(!) уже.

вы не хотите заставлять функцию ждать, потому что JavaScript должен быть неблокирующим. Вместо того, чтобы возвращать обещание в конце функции, то вызывающая функция может использовать обещание, чтобы получить ответ сервера.

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

//Or return query.find(); 

вы на самом деле не используете обещания здесь. Разбор позволяет использовать обратные вызовы или обещания; ваш выбор.

чтобы использовать обещания, выполните следующие действия:

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

Теперь, чтобы выполнить материал после завершения обещания, вы можете просто выполнить его внутри обратного вызова promise внутри 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");
});