回调的乐趣...您需要了解如何使用回调时程序流程的工作原理。这可以用一个非常简单的例子来看。
例子:
function doWork(callback) {
console.log(2);
setTimeout(callback, 1000);
}
function master() {
console.log(1);
doWork(function() {
console.log(3);
});
console.log(4);
}
master();
预期的结果将在propper顺序1,2,3,4控制台日志,但运行的例子,当你看到一些奇怪的日志是乱序1,2,4,3。这是因为3日志记录发生在doWork
完成后,而4日志记录在启动doWork
后发生,而不是等待它完成。
异步:
你可以做很多与异步库,但是要记住最重要的是,回调函数总是收到错误作为第一个参数后面的参数你想传递给列表中的下一个函数。
您链接的gist未设置为返回该方式。您可以修复它或在代码中处理它。首先让刚刚使用的功能是:
使用现有getCoords:
async.waterfall([
function(callback) {
// getCoords only returns one argument
getCoords (function(mapData) {
// First argument is null because there
// is no error. When calling the waterfall
// callback it *must* happen inside the getCoords
// callback. If not thing will not work as you
// have seen.
callback(null, mapData);
});
},
function(mapData, callback) {
// Do work with the results of the 1st step
// in the waterfall.
// Finish the water fall
callback(null, mapData);
}
], function(err, result) {
if (err) {
console.log(err);
return;
}
console.log(result);
});
现在有与getCoords
两个问题。首先,它不会将正确的参数返回给它的回调,其次它并不总是使用它的回调。第二个问题是巨大的,因为它会导致您的程序挂起并中断。
我已经在函数中修改了2个修正。
固定getCoords:
function getCoords (callback) {
var query = new Parse.Query('userGeoCoordinates');
query.exists('location')
query.find({
success: function (result) {
for (var i = 0; i < result.length; i++) {
var object = result[ i ];
var user = {};
user.userId = object.get('userId');
user.coords = [];
if (!user_dedupe(user.userId)) {
all_users.push(user);
}
}
for (var i = 0; i < all_users.length; i++) {
for (var j = 0; j < result.length; j++) {
var object = result [ j ];
if(object.get('userId') == all_users[ i ].userId) {
all_users[i].coords.push(
[ object.get('location')._longitude , object.get('location')._latitude ]
);
}
}
}
// This is the original callback, let fix it
// so that it uses the normal return arguments
// callback(all_users);
// Return null for no error, then the resutls
callback(null, all_users);
},
error: function(error) {
// Here is the second, bigger, issue. If the
// getCoords had an error, nothing the callback
// isn't called. Lets fix this
// console.log('error');
// Return the error, an no results.
callback(error);
}
});
}
有了固定可以简化您的瀑布getCoords
功能:
1简体瀑布:
async.waterfall([
function(callback) {
// getCoords returns the expected results
// so just pass in our callback
getCoords (callback);
},
function(mapData, callback) {
// Do work with the results of the 1st step
// in the waterfall.
// Finish the water fall
callback(null, mapData);
}
], function(err, result) {
if (err) {
console.log(err);
return;
}
console.log(result);
});
但是异步有一个很好的功能。如果你的瀑布步骤只是调用一个返回期望结果的函数,你可以通过使用async.apply进一步简化它。
2ST简体瀑布:
async.waterfall([
async.apply(getCoords),
function(mapData, callback) {
// Do work with the results of the 1st step
// in the waterfall.
// Finish the water fall
callback(null, mapData);
}
], function(err, result) {
if (err) {
console.log(err);
return;
}
console.log(result);
});
这是你正在做的,如果是这样,为什么你甚至需要异步,只需将'getCoords'回调里面的'getEmail'功能? – adeneo
@adeneo这可能只是philsometypaway需要实现连续传递样式的较大实现的一小部分。 –
@JasonAller是正确的 - 我将需要链接在一起的一堆。感谢您的帮助! – philsometypaway