需要进一步的帮助,使javascript同步生成器处理异步函数

Need further help in making javascript sync generator handle async functions

本文关键字:处理 函数 异步 同步 javascript 进一步 帮助      更新时间:2023-09-26

我是Node JS的相对新手。我需要同步调用异步函数(http request())。Kylie Simpson的这篇文章对我帮助很大;特别是这个代码位正是我需要的:

function request(url) {
    // this is where we're hiding the asynchronicity,
    // away from the main code of our generator
    // `it.next(..)` is the generator's iterator-resume
    // call
    makeAjaxCall( url, function(response){
        it.next( response );
    } );
    // Note: nothing returned here!
}
function *main() {
    var result1 = yield request( "http://some.url.1" );
    var data = JSON.parse( result1 );
    var result2 = yield request( "http://some.url.2?id=" + data.id );
    var resp = JSON.parse( result2 );
    console.log( "The value you asked for: " + resp.value );
}
var it = main();
it.next(); // get it all started

但是我需要更进一步:我需要能够将result1传递给另一个函数(下面示例中的processResult()),然后如果满足某些条件,该函数将调用request()。像这样:

function request(url) {
    makeAjaxCall( url, function(response){
        it.next( response );
    } );
}
function processResult(resSet) {
    if (resSet.length>100)
        return request("http://some.url.1/offset100");
    else
        write2File(resSet);
}
function *main() {
    var result1 = yield request( "http://some.url.1" );
    processResult(result1)
}
var it = main();
it.next();

但是当我尝试这样做时,request("http://some.url.1/offset100")不返回任何值。什么好主意吗?

但是当我尝试这样做时,request("http://some.url.1/offset100")不返回任何值。

除了使用yield暂停外,生成器函数与其他函数一样同步执行。

function processResult(resSet){}的调用是一个同步调用,在异步function request(url) {}完成之前返回function *main() {}。相反,您需要继续从生成器函数内部生成对异步function request(url){}的调用。你可以这样重构你的代码:

function processResult(resSet) {
    if (resSet.length>100)
        return true;
    else
        write2File(resSet); // assuming that this function is synchronous
        return false; // not necessary as the function in this case returns `undefined` by default which coerces to false - but it illustrates the point
}
function *main() {
    var result1 = yield request( "http://some.url.1" );
    if(processResult(result1)) {
        var offset100 = yield request("http://some.url.1/offset100");
    }
    // do something with offset100
var it = main();
it.next();