简体   繁体   English

javascript保证不能按正确的顺序工作

[英]javascript promise not working in a right sequence

So basically I have a web application that uses promise. 所以基本上我有一个使用promise的Web应用程序。 Below is my code: 下面是我的代码:

for(var key in data){               
    var promise = getDataFNLN(idOfReviewee);
    promise.then(function(returnedFnLn){
        count = count + +1;
        AllReviewee[count] = returnedFnLn;

        console.log("firsst");
        return getDataFNLN(idOfReviewer[count]);
    }).then(function(returnedFnLn){
        count1 = count1 + +1;
        AllReviewer[count1] = returnedFnLn;

        console.log("second");
    })
}

function getDataFNLN(idRev){
    return new Promise (function(resolve,reject){
        getDataToUsers = firebase.database().ref("users").child(idRev);
        getDataToUsers.once("value",function(snap){ 
            var fnLn =snap.val();
            var first = fnLn.firstname;
            var second = fnLn.lastname;
            forPromiseFnLn = first.concat(" ",second);

            resolve(forPromiseFnLn);    
        });
    });
}

Assuming that the data variable in the for loop has 4 data, so it will loop four times. 假设for循环中的data变量有4个数据,那么它将循环四次。 And through promise the output of the console must be: 通过promise,控制台的输出必须为:

first 第一
second 第二
first 第一
second 第二
first 第一
Second 第二
First 第一
Second 第二

but instead it outputs like this: 但相反,它输出如下:

first 第一
first 第一
first 第一
first 第一
Second 第二
Second 第二
Second 第二
Second 第二

You could iterate your function by passing an index and incrementing this counter in the last .then. 您可以通过传递索引并在最后一个.then中递增此计数器来迭代您的函数。

I seem to be missing where the key is used in your for loop. 我似乎不知道在for循环中使用密钥的位置。 I am assuming this is the idOfReviewee. 我假设这是idOfReviewee。

function iterateData(data, index) {
    // Make sure to check here for data length to not get undefined vars.          
    var promise = getDataFNLN(data[index]);
    return promise.then(function(returnedFnLn){
        count = count + +1;
        AllReviewee[count] = returnedFnLn;

        console.log("firsst");
        return getDataFNLN(idOfReviewer[count]);
    }).then(function(returnedFnLn){
        count1 = count1 + +1;
        AllReviewer[count1] = returnedFnLn;

        console.log("second");

        // Continue the loop incrementing the index
        return iterateData(data, ++index)
    })
}

function getDataFNLN(idRev){
    return new Promise (function(resolve,reject){
        getDataToUsers = firebase.database().ref("users").child(idRev);
        getDataToUsers.once("value",function(snap){ 
            var fnLn =snap.val();
            var first = fnLn.firstname;
            var second = fnLn.lastname;
            forPromiseFnLn = first.concat(" ",second);

            resolve(forPromiseFnLn);    
        });
    });
}

Maybe you could use https://github.com/LvChengbin/sequence for your case. 也许您可以针对您的案例使用https://github.com/LvChengbin/sequence This library can help you to run promises in sequence and also has other APIs for managing the sequence. 该库可以帮助您按顺序运行promise,并且还具有其他用于管理序列的API。

You can modify your code like this: 您可以这样修改代码:

var steps = [];

for(var key in data){
    steps.push( function() {        
        var promise = getDataFNLN(idOfReviewee);
        promise.then(function(returnedFnLn){
            count = count + +1;
            AllReviewee[count] = returnedFnLn;

            console.log("firsst");
            return getDataFNLN(idOfReviewer[count]);
        }).then(function(returnedFnLn){
            count1 = count1 + +1;
            AllReviewer[count1] = returnedFnLn;

            console.log("second");
        });
        return promise;
    } );
}

Sequence.all( steps ).then( results => {
    // results is a result list of each step.
} ).catch( e => {
    // any one step in the sequence failed
} );

Even push all steps into the sequence. 甚至将所有步骤推入序列。

var steps = [];

for(var key in data){
    steps.push( function() {
        return getDataFNLN( idOfReviewee );
    } );

    steps.push( function( result ) {        
        var returnedFnLn = result.value;

        count = count + +1;

        AllReviewee[count] = returnedFnLn;

        console.log("firsst");

        return getDataFNLN(idOfReviewer[count]);
    } );

    steps.push(function( result ){
        var returnedFnLn = result.value;
        count1 = count1 + +1;
        AllReviewer[count1] = returnedFnLn;    
        console.log("second");
    } );
}

Sequence.all( steps ).then( results => {
    // results is a result list of each step.
} );

If the steps would be changed after initialized, you can use new Sequence : 如果在初始化后将更改步骤,则可以使用new Sequence

const sequence = new Sequence();

sequence.on( 'success', ( result, index, results ) => {
    // this would be executed while each step succeeded
} );

sequence.on( 'failed', ( result, index, results ) => {
    // this would be executed while each step failed.
} );

sequence.end( 'end', () => {
    // this function will execute after all steps finished.
} );

sequence.append( your step(s) here );

You can get more information from the documentation on Github. 您可以从Github上的文档中获取更多信息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM