gpt4 book ai didi

javascript - 嵌套在 async.js waterfall 中的异步函数

转载 作者:数据小太阳 更新时间:2023-10-29 05:54:58 28 4
gpt4 key购买 nike

免责声明:非工程师,对 JS 非常陌生

大家好 - 我正在尝试利用 async.js 模块将一组函数链接在一起。我想要的输出是遍历 mapData(对象数组),然后再将其传递给最终函数(现在 - 只是 console.log(result)。

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 );
});

但是,getCoords 包含另一个异步函数(找到 here )。我看到的是第一个回调 (null, mapData) 在它返回之前发生,导致 null 结果。

我如何构造它以便 getCoords 在继续下一个 block 之前返回 mapData?我可能遗漏了一些非常明显的东西,谢谢!

最佳答案

回调的乐趣...您需要了解使用回调时程序流程是如何工作的。这可以通过一个非常简单的例子看出。

示例:

function doWork( callback ) {
console.log( 2 );
setTimeout(callback, 1000);
}

function master () {
console.log(1);

doWork(function () {
console.log(3);
});

console.log(4);
}
master();

预期的结果是控制台日志的正确顺序为 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 函数,您可以简化您的 waterfall 流:

第一个简化的 waterfall :

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 有一个很好的特性。如果您的 waterfall 步骤只是调用一个返回预期结果的函数,您可以使用 async.apply 进一步简化它。

第二个简化的 waterfall :

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 );
});

关于javascript - 嵌套在 async.js waterfall 中的异步函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22733575/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com