我仍然在努力应对承诺,但感谢社区在这里取得了一些进展。
我有一个简单的JS函数来查询Parse数据库。它应该返回结果数组,但显然由于查询的异步性质(因此是promises),函数在结果之前返回,留下一个未定义的数组。
我需要做些什么来使这个函数等待承诺的结果?
这是我的代码:
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");
}
});
}
答案 0 :(得分:50)
而不是返回resultsArray
,而是返回结果数组的承诺,然后返回呼叫站点上的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's own blog post about it中查看更多使用解析承诺的示例。
答案 1 :(得分:10)
我需要做些什么来使这个函数等待承诺的结果?
使用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');
}
答案 2 :(得分:2)
您不希望让函数等待,因为JavaScript旨在实现非阻塞。 而是在函数结束时返回promise,然后调用函数可以使用promise来获取服务器响应。
var promise = query.find();
return promise;
//Or return query.find();
答案 3 :(得分:2)
你实际上并没有在这里使用承诺。 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");
});
答案 4 :(得分:0)
我有同样的问题,所以我维护了一些代码,代码需要调用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
....