问题描述
我需要在代码中使用bluebird,我也不知道如何使用它.我的代码包含嵌套循环.当用户登录时,我的代码将运行.它将开始在用户下查找任何文件,并且如果有文件,它将循环搜索以获取文件的名称,因为该名称存储在字典中.一旦获得名称,它将名称存储在数组中.一旦存储了所有名称,它将在res.render()中传递.
I need to use bluebird in my code and I have no idea how to use it. My code contains nested loops. When the user logs in, my code will run. It will begin to look for any files under the user, and if there are files then, it will loop through to get the name of the files, since the name is stored in a dictionary. Once it got the name, it will store the name in an array. Once all the names are stored, it will be passed along in res.render().
这是我的代码:
router.post('/login', function(req, res){
var username = req.body.username;
var password = req.body.password;
Parse.User.logIn(username, password, {
success: function(user){
var Files = Parse.Object.extend("File");
var object = [];
var query = new Parse.Query(Files);
query.equalTo("user", Parse.User.current());
var temp;
query.find({
success:function(results){
for(var i=0; i< results.length; i++){
var file = results[i].toJSON();
for(var k in file){
if (k ==="javaFile"){
for(var t in file[k]){
if (t === "name"){
temp = file[k][t];
var getname = temp.split("-").pop();
object[i] = getname;
}
}
}
}
}
}
});
console.log(object);
res.render('filename', {title: 'File Name', FIles: object});
console.log(object);
},
error: function(user, error) {
console.log("Invalid username/password");
res.render('logins');
}
})
});
该代码不起作用,因为在第一个和第二个console.log(object)上,我得到一个空数组.我想在该数组中得到一项,因为我保存了一个文件
The code doesn't work, because on the first and second console.log(object), I get an empty array. I am suppose to get one item in that array, because I have one file saved
推荐答案
JavaScript代码从上到下都进行了解析,但是不一定要按照异步代码的顺序执行.问题是您在登录函数的成功回调中包含了日志语句,但是在查询的成功回调中是 NOT .
JavaScript code is all parsed from top to bottom, but it doesn't necessarily execute in that order with asynchronous code. The problem is that you have the log statements inside of the success callback of your login function, but it's NOT inside of the query's success callback.
您有几种选择:
- 将console.log语句移动到内部成功回调内部,以便尽管它们可以在加载时进行解析,但是直到两个回调都被调用时,它们才执行.
- 承诺传统上依赖并调用回调函数的函数,然后将返回的值挂起处理程序以将诺言链接在一起.
第一种选择是根本不使用promise,而仅依赖于回调.为了使代码扁平化,您需要使这些函数分散,然后将它们链接起来.
The first option is not using promises at all, but relying solely on callbacks. To flatten your code you will want to promisify the functions and then chain them.
我不熟悉您在成功和错误回调中使用的语法,也不熟悉Parse.通常,您会执行以下操作:
I'm not familiar with the syntax you're using there with the success and error callbacks, nor am I familiar with Parse. Typically you would do something like:
query.find(someArgsHere, function(success, err) {
});
但是随后您将不得不在其中嵌套另一个回调,并在其中嵌套另一个回调.为了拉平"金字塔,我们使函数返回一个promise,然后可以将promise链接起来.假设Parse.User.logIn是一个回调样式的函数(与Parse.Query.find一样),则您可以执行以下操作:
But then you would have to nest another callback inside of that, and another callback inside of that. To "flatten" the pyramid, we make the function return a promise instead, and then we can chain the promises. Assuming that Parse.User.logIn is a callback-style function (as is Parse.Query.find), you might do something like:
var Promise = require('bluebird');
var login = Promise.promisify(Parse.User.logIn);
var find = Promise.promisify(Parse.Query.find);
var outerOutput = [];
return login(yourArgsHere)
.then(function(user) {
return find(user.someValue);
})
.then(function(results) {
var innerOutput = [];
// do something with innerOutput or outerOutput and render it
});
这对于您可能习惯的同步代码来说应该看起来很熟悉,除了不是将返回的值保存到变量中,然后将该变量传递给下一个函数调用,而是使用"then"处理程序将promise链接在一起.您可以在第二个then处理程序中创建整个输出变量,也可以在甚至启动此promise链之前声明变量输出,然后它将在所有这些函数的范围内.我已经在上面向您展示了这两个选项,但是显然您不需要定义这两个变量并为其分配值.只需选择适合您需求的选项即可.
This should look familiar to synchronous code that you might be used to, except instead of saving the returned value into a variable and then passing that variable to your next function call, you use "then" handlers to chain the promises together. You could either create the entire output variable inside of the second then handler, or you can declare the variable output prior to even starting this promise chain, and then it will be in scope for all of those functions. I have shown you both options above, but obviously you don't need to define both of those variables and assign them values. Just pick the option that suits your needs.
您还可以使用Bluebird的promisifyAll()函数用等效的promise-returning函数包装整个库.它们在后缀为Async的库中都具有相同的功能名称.因此,假设Parse库包含名为someFunctionName()和someOtherFunc()的回调样式函数,则可以执行以下操作:
You can also use Bluebird's promisifyAll() function to wrap an entire library with equivalent promise-returning functions. They will all have the same name of the functions in the library suffixed with Async. So assuming the Parse library contains callback-style functions named someFunctionName() and someOtherFunc() you could do this:
var Parse = Promise.promisifyAll(require("Parse"));
var promiseyFunction = function() {
return Parse.someFunctionNameAsync()
.then(function(result) {
return Parse.someOtherFuncAsync(result.someProperty);
})
.then(function(otherFuncResult) {
var something;
// do stuff to assign a value to something
return something;
});
}
这篇关于如何在嵌套for循环中使用Promise Bluebird?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!