2016-06-23 102 views
2

我想链3承诺在一起,但有一些行为,我不知道有关resolvereject功能。我已经简化我的代码,以便提出这样的问题:本地JavaScript链接承诺

function testP(num) { 
    return new Promise((resolve, reject) => { 
    console.log('Do Work', num); 
    reject(num); 
    }); 
} 

function testPromises() { 
    return new Promise((resolve, reject) => { 
     testP(1) 
     .then(testP(2)) 
     .then(testP(3)) 
     .then(resolve) 
     .catch(reject); 
    }); 
}; 

const theTest = testPromises().then(()=>{ 
    console.log("all done"); 
}).catch(err => { 
    console.log("ERR", err); 
}); 

而我所看到的在我的输出是:

Do Work 1 
Do Work 2 
Do Work 3 
ERR 1 

为什么代码得到Do Work 2Do Work 3,如果第一诺言立即命中reject?我的理解是then函数在执行前等待resolvereject的承诺。

+2

顺便说一句'返回新无极((解析,拒绝)=> {不便( )。然后(smth2)。然后(解析).catch(拒绝); })'是反模式。使用'return smth()。then(smth2);'更好。 –

回答

5

因为当你做

.then(testP(2)) 

电话testP立即无条件,传入2,然后通过它的返回值到.then,完全相同的方式foo(bar())电话bar并将其返回值到foo

此代码:

testP(1) 
    .then(testP(2)) 
    .then(testP(3)) 
    .then(resolve) 
    .catch(reject); 

这样进行评估(一些细微的细节省略):

  • 呼叫testP具有值1,并用记住所得到的值作为p1
  • 呼叫testP价值2
  • 拨打电话p1.then与该呼叫的结果和remembe R中的结果值作为P2
  • 呼叫testP与价值3
  • 呼叫p2.then与调用的结果,并记住所得到的值作为p3
  • 呼叫p3.then与价值resolve并记住结果作为p4
  • 呼叫p4.catch与值reject
  • 呼叫从所述第一呼叫的reject功能testP与值1
  • testPromises调用reject与如果希望testP等到第一个得到解决,你不呼叫它,你传递给它一个参考值1

.then(testP) 

如果你希望它有一个论点烤制,使用bind

.then(testP.bind(null, 2)) 

或内联函数:

.then(function() { 
    return testP(2); 
}) 

(需要与Promise浏览器)

function testP(num) { 
 
    return new Promise((resolve, reject) => { 
 
    console.log('Do Work', num); 
 
    reject(num); 
 
    }); 
 
} 
 

 
function testPromises() { 
 
    return new Promise((resolve, reject) => { 
 
     testP(1) 
 
     .then(testP.bind(null, 2)) 
 
     .then(testP.bind(null, 3)) 
 
     .then(resolve) 
 
     .catch(reject); 
 
    }); 
 
}; 
 

 
const theTest = testPromises().then(()=>{ 
 
    console.log("all done"); 
 
}).catch(err => { 
 
    console.log("ERR", err); 
 
});

+0

值得一提的是,传递给'then'的非函数类型是无稽之谈,并且被忽略(因为'testP(2)'被评估为'Promise') – ftor