Javascript 如何在返回函数变量之前等待承诺完成?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/27759593/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I wait for a promise to finish before returning the variable of a function?
提问by mac_55
I'm still struggling with promises, but making some progress thanks to the community here.
我仍在为承诺而苦苦挣扎,但由于这里的社区,我取得了一些进展。
I have a simple JS function which queries a Parse database. It's supposed to return the array of results, but obviously due to the asynchronous nature of the query (hence the promises), the function returns before the results, leaving me with an undefined array.
我有一个简单的 JS 函数来查询 Parse 数据库。它应该返回结果数组,但显然由于查询的异步性质(因此是承诺),该函数在结果之前返回,给我留下一个未定义的数组。
What do I need to do to make this function wait for the result of the promise?
我需要做什么才能让这个函数等待 Promise 的结果?
Here's my code:
这是我的代码:
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");
}
});
}
采纳答案by Benjamin Gruenbaum
Instead of returning a resultsArrayyou return a promise for a results array and then thenthat on the call site - this has the added benefit of the caller knowing the function is performing asynchronous I/O. Coding concurrency in JavaScript is based on that - you might want to read this questionto get a broader idea:
而不是返回一个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
});
You can see more examples of using parse promises with queries in Parse's own blog post about it.
您可以在Parse 自己的关于它的博客文章中看到更多使用 parse promise 和查询的示例。
回答by Martin Meeser
What do I need to do to make this function wait for the result of the promise?
我需要做什么才能让这个函数等待 Promise 的结果?
Use async/await(NOT Part of ECMA6, but
available for Chrome, Edge, Firefox and Safari since end of 2017, see canIuse)
MDN
使用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');
}
Added due to comment: An async function always returns a Promise, and in TypeScript it would look like:
由于评论而添加:异步函数总是返回一个 Promise,在 TypeScript 中它看起来像:
async function waitForPromise(): Promise<string> {
// let result = await any Promise, like:
let result = await Promise.resolve('this is a sample promise');
}
回答by Trace
You don't want to make the function wait, because JavaScript is intended to be non-blocking. Rather return the promise at the end of the function, then the calling function can use the promise to get the server response.
你不想让函数等待,因为 JavaScript 是非阻塞的。而是在函数末尾返回承诺,然后调用函数可以使用承诺来获取服务器响应。
var promise = query.find();
return promise;
//Or return query.find();
回答by mash
You're not actually using promises here. Parse lets you use callbacks or promises; your choice.
您实际上并没有在这里使用承诺。Parse 允许您使用回调或承诺;你的选择。
To use promises, do the following:
要使用 Promise,请执行以下操作:
query.find().then(function() {
console.log("success!");
}, function() {
console.log("error");
});
Now, to execute stuff after the promise is complete, you can just execute it inside the promise callback inside the then()call. So far this would be exactly the same as regular callbacks.
现在,要在承诺完成后执行内容,您可以在调用内的承诺回调中执行它then()。到目前为止,这与常规回调完全相同。
To actually make good use of promises is when you chain them, like this:
真正善用 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");
});
回答by dungphanxuan
I have same problem, so I maintain some code, code need call ajax done to process another task, here my code
我有同样的问题,所以我维护了一些代码,代码需要调用 ajax done 来处理另一个任务,这里是我的代码
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 function
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)
}
});
})
};
and i get result
我得到了结果
Another todo
Output
Ajax Done
….
……

