2016-12-12 50 views
-1

我有Node.js应用程序。为什么这两个代码片段不能以相同的方式工作?承诺 - 传递解析函数和包装函数之间的区别

1)

function myFn1() { 
    return new Promise(function(resolve, reject) { 
     myFn2().then(function(url) { 
      resolve(url); 
     }); 
    }); 
} 

2)

function myFn1() { 
    return new Promise(function(resolve, reject) { 
     myFn2().then(resolve); 
    }); 
} 

常见:

function myFn2() { 
    return new Promise(function(resolve, reject) { 
     var url = 'example.com'; 
     resolve(url); 
    }); 
} 

我把它与

myFn1().then(function(url) { 
    console.log(url); 
}); 

与代码1)网址正确通过,但与代码2)网址未定义。 在这两种情况下,我不传递单参数函数吗?有什么不同?

+3

如果我解决这个错字(了'()''在()函数myFn2' function'后'),都在为我工作(他们应该):https://jsfiddle.net/rorgqrjj/我使用“code 1”作为“myFn1A”,“code 2”作为“myFn1B”。 –

+0

...但当然,你不希望'myFn1'在任何情况下都以这种方式工作。它不必要地创造新的承诺。你需要'function myFn1(){return myFn2()。then(function(url){/ *做一些事情,大概是这样,然后:*/return url;}); ''或类似的。 –

+0

'myFn2()。then(resolve);' 应该不是 'myFn2()。then(url => resolve(url));' 单参数函数是什么意思? –

回答

1

首先,避免承诺反模式。当你已经有了一个承诺时,只要使用它并返回即可。不要把它包装在一个新的承诺中。除了效率低下之外,犯错误真的很容易,特别是在错误处理方面(你有)。

所以,你应该做的是:

function myFn1() { 
    return myFn2().then(function(url) { 
     // do some modification to url and then return that 
     // or some other processing here 
     return url; 
    }); 
} 

所以根本没有必要在其他承诺从myFn2()包裹退回承诺。在你的具体情况下,你默默地从内心的承诺中发现任何错误,并且他们不会传播给myFn1()的调用者,这几乎总是一个错误,有时候是一个非常严重的错误。

而且,如果你真的没有什么了.then()处理程序里面做,那么你甚至不需要它要么:

function myFn1() { 
    // some code here 
    return myFn2(); 
} 

至于原来的问题,你的两个代码段1)和2)以相同的方式工作,并且没有有意义的行为差异,除了进行额外的函数调用并使用更多的栈来实现。

当你这样做:

myFn2().then(resolve); 

你告诉.then()调用resolve与任何参数通常会被传递到.then()处理程序。由于你的情况这样的说法是url,则:

.then(resolve); 

是完全一样的:

.then(function(url) { 
    resolve(url); 
}); 

他们两个呼叫resolve具有完全相同的参数。第一种是简写,当.then()将用于回调的参数恰好是你想要的函数的参数时应该使用。如果函数的参数不完全相同,或者显然,如果在处理函数中有多个函数调用,则应该使用第二个参数。所以,如果你想打电话决心之前加入".jpg"扩展URL,然后你要做的:

.then(function(url) { 
    resolve(url + ".jpg"); 
}); 

随着码1)网址是否正确通过,但与代码2 )网址是 未定义。在这两种情况下,我不传递单参数函数吗?什么是 的区别?

假设由myFn2()返回的承诺解析为url,那么就应该有你的场景#1和#2之间没有什么区别。由myFn1()返回的承诺应该以任何方式解析为相同的值。

现在,如果您在.then()处理程序中放置了一些代码,并忘记从该处理程序返回所需的值,则承诺的解析值将变为undefined,这可能是您的真实代码中发生的情况。所以,如果你这样做:

function myFn1() { 
    return myFn2().then(function(url) { 
     console.log(url); 
    }); 
} 

myFn1().then(function(url) { 
    console.log(url);  // will be undefined 
}) 

因为你没有返回从.then()处理器的myFn1内部的任何物件。这意味着返回值是undefined,所以承诺承担了该返回值。请记住,如果您希望您的承诺具有特定的解决价值,您必须从链中的任何.then()处理程序返回。

function myFn1() { 
    return myFn2().then(function(url) { 
     console.log(url); 
     return url;   // make sure the promise retains this resolved value 
    }); 
} 
+1

甚至更​​短,'const myFn1 = myFn2;'。 –

+0

@torazaburo - 这里的假设是,'myFn1'不仅仅是调用'myFn2'。 – jfriend00

相关问题