javascript承诺无法以正确的顺序工作

时间:2018-01-15 15:53:48

标签: javascript php jquery html

所以基本上我有一个使用promise的Web应用程序。以下是我的代码:

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

假设for循环中的数据变量有4个数据,那么它将循环四次。并且通过承诺控制台的输出必须是:

  

第一
  第二
  第一
  第二
  第一
  第二
  首先
  第二

但是输出如下:

  

第一
  第一
  第一
  第一
  第二
  第二
  第二
  第二

2 个答案:

答案 0 :(得分:0)

您可以通过传递索引并在最后一个.then。

中递增此计数器来迭代您的函数

我似乎错过了在你的for循环中使用密钥的地方。我假设这是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);    
        });
    });
}

答案 1 :(得分:0)

也许您可以使用https://github.com/LvChengbin/sequence来处理您的案件。 该库可以帮助您按顺序运行promises,还有其他API来管理序列。

您可以像这样修改代码:

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

甚至将所有步骤都按顺序推进。

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

如果在初始化后更改步骤,您可以使用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 );

您可以从Github上的文档中获取更多信息。