回調的樂趣...您需要了解如何使用回調時程序流程的工作原理。這可以用一個非常簡單的例子來看。
例子:
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