phi*_*way 5 javascript asynchronous node.js async.js
免责声明:非工程师,对JS来说很新
嘿所有 - 我正在尝试利用async.js模块将一组函数链接在一起.我想要的输出是迭代mapData(对象数组),然后将它传递给最终函数(现在 - 只是console.log(结果)).
async.waterfall([
function( callback ) {
getCoords ( function( data ) {
mapData = data;
});
callback(null, mapData);
},
function( mapData, callback ) {
//getEmail ( mapData );
callback( null, mapData );
}
], function( err, result ) {
console.log( result );
});
Run Code Online (Sandbox Code Playgroud)
但是,getCoords包含另一个异步函数(在此处找到).我所看到的是第一个回调(null,mapData)在它返回之前发生,导致null结果.
如何构建这个以便在进入下一个块之前getCoords返回mapData?我可能错过了一些非常明显的东西,谢谢!
回调乐趣......您需要了解程序流在使用回调时的工作原理.这可以通过一个非常简单的例子看到.
例:
function doWork( callback ) {
console.log( 2 );
setTimeout(callback, 1000);
}
function master () {
console.log(1);
doWork(function () {
console.log(3);
});
console.log(4);
}
master();
Run Code Online (Sandbox Code Playgroud)
预期的结果将是适配器顺序1,2,3,4中的控制台日志.但是当运行该示例时,您会看到一些奇怪的事情,因为日志乱序为1,2,4,3.这是因为3的记录发生了doWork完成后,在启动后发生4的记录,而doWork不是等待它完成.
异步:
您可以使用异步库做很多事情,但最重要的是要记住,回调函数总是接收错误作为第一个参数,后跟要传递给列表中下一个函数的参数.
您链接到的要点不是设置为以这种方式返回.您可以修复它或在代码中处理它.首先让我们按原样使用该功能:
使用现有的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 );
});
Run Code Online (Sandbox Code Playgroud)
现在有两个问题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 );
}
});
}
Run Code Online (Sandbox Code Playgroud)
getCoords修复此功能后,您可以简化瀑布:
第一个简化瀑布:
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 );
});
Run Code Online (Sandbox Code Playgroud)
但是async有一个很好的功能.如果您的瀑布步骤只是调用一个返回期望结果的函数,您可以使用async.apply进一步简化它.
第2个简化瀑布:
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 );
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
9674 次 |
| 最近记录: |