嵌套的Promise在"错误"中执行订购

时间:2017-05-26 14:14:36

标签: javascript node.js promise

我尝试以+模式打开2个文件,然后尝试阅读其内容并将其发回给用户。我使用嵌套回调实现了它,但我想尝试使用Promises,因此我写了以下内容:

var chain1 = [];  
var c1Promise1 = new Promise(func(res,rej){  
   fs.open('path','a+',func(err,fd){  
     if(err)  
       {rej(err)}  
     else  
       {res(fd)}  
     })  
chain1.push(c1Promise1)  
//Same thing for the second promise, just different path  
Promise.all(chain1).then(fds=>{
    var chain2 = []  
    var c2Promise1 = new Promise(func(res,rej){  
       fs.readFile(fds[0],'utf-8',func(err,data){
          console.log("data1 = " + data)  
          if(err){  
            rej(err)
          }  
          else{  
            res(data)  
          }  
       })  
})
chain2.push(c2Promise1)
//Same thing for c2Promise2 but different fd (fds[1]) and .log("data2 = " + data)
Promise.all(chain2).then(data=>{
       console.log("data3 and 4 = " + data[0] + ' ' + data[1])
   },err=>next(err))
},err=>next(err))  

On console i get:  
"data3 and 4" = undefined undefined    
"data1 = " actual data in the file  
"data2 = " actual data in the file.   

我错过了什么?这不应该像data1,data2那样,只有数据3和4!谢谢你的帮助

2 个答案:

答案 0 :(得分:1)

Promise.all()马上返回是不等待承诺完成的 因此,在您的情况下,第一个Promise.all以下的所有内容都应位于.then()块中。

顺便说一句,这种代码很难阅读。您可以尝试使用直接处理承诺的fs = require('mz/fs')。也许使用async / await。

像: let fs = require('ms/fs'); let data1 = await fs.readFile(path1, 'utf8'); let data2 = await fs.readFile(path2, 'utf8');

答案 1 :(得分:0)

承诺是异步的。因此,一个接一个地开始多个承诺并不意味着它们被执行/它们按顺序完成。

如果我的理解是正确的,你的代码基本上会执行以下操作(psuedo-js-code):

var chain1 = [c1promise1, c2promise2];
Promise.all(chain1).then( // wait for execution
    var chain2 = [c2promise1, c2promise2];
);
Promise.all(chain2).then( // at this point in time the execution of chain1 doesn't have to be finished!
    // do sth
);

如果你想按顺序执行链(!链中的承诺仍然不必按顺序执行)你应该链接承诺:

var chain1 = [c1promise1, c2promise2];
Promise.all(chain1).then( // wait for execution
    return [c2promise1, c2promise2];
).all(chain2).then(
    // do sth
);

甚至更好:使用Nico提出的async / await