返回承诺与返回承诺中的未定义之间的区别
Difference between returning a promise vs returning undefined inside a promise
我不确定我是否理解这两种常见情况之间的区别。
假设我们有这个:
user.save().then(function(val){
anotherPromise1(val);
}).then(function(val){
anotherPromise2(val);
}).catch(function(err){
});
对比:
user.save().then(function(val){
return anotherPromise1(val);
}).then(function(val){
return anotherPromise2(val);
}).catch(function(err){
});
我知道这会有所不同,但具体情况如何?
如果您没有 return 来自 then
回调的值,您实际上是在 returning undefined
。下一个 then
回调将立即 运行,并将 undefined
视为分辨率值。
如果您 return 来自 then
回调的承诺,则第二个 then
回调会等待该承诺(间接地,但这并不重要),并且当promise 已解决,从该 promise 中获取分辨率值。
(这包含在 Promises/A+ spec 中的 then
规范中,但略有遗漏 — 它没有明确提及如果 onFulfilled
不 return 任何东西,但在 JavaScript 中,调用函数 总是 给你一个结果值;如果函数没有明确地 return 东西,undefined
是调用它的结果。Java脚本没有 void
方法的概念 a'la C/C#/C++/Java.)
你可以在这个脚本中看到它live copy on Babel's REPL:
let start = Date.now();
function elapsed() {
let rv = String(Date.now() - start);
while (rv.length < 4) {
rv = "0" + rv;
}
return rv;
}
function anotherPromise(type, val) {
console.log(`${elapsed()}: anotherPromise[${type}] got ${val}`);
return new Promise(resolve => {
setTimeout(() => { resolve(val * 2); }, 1000);
});
}
function anotherPromise2(type, val) {
console.log(`${elapsed()}: anotherPromise2[${type}] got ${val}`);
return new Promise(resolve => {
setTimeout(() => { resolve(val * 3); }, 10);
});
}
let user = {
save: () => {
return new Promise(resolve => {
setTimeout(() => {
resolve(42);
}, 10);
});
}
}
// Without return
user.save().then(function(val){
anotherPromise("without", val);
}).then(function(val){
anotherPromise2("without", val);
}).then(function() {
console.log(`${elapsed()}: All done`);
}).catch(function(err){
});
user.save().then(function(val){
return anotherPromise("with", val);
}).then(function(val){
return anotherPromise2("with", val);
}).then(function() {
console.log(`${elapsed()}: All done`);
}).catch(function(err){
});
输出是(例如):
0015: anotherPromise[without] got 42
0017: anotherPromise2[without] got undefined
0018: All done
0020: anotherPromise[with] got 42
1021: anotherPromise2[with] got 84
1032: All done
注意 without a return 和 with a return:
之间的区别
Without, anotherPromise2
被立即调用(正如我们可以从经过的时间值中看到的那样)并收到 undefined
.
和,anotherPromise2
等待anotherPromise
的解析发生,然后收到84
(anotherPromise
的分辨率值)
不同的是这件事的时机。
在示例 1 中,save
承诺已完成,anotherPromise1
将被调用,因为没有承诺 returned,anotherPromise2
将被调用立即地。
如果您 return anotherPromise1
函数的承诺,anotherPromise
的调用将在 anotherPromise1
被解析后发生。
因此示例 1:anotherPromise1
和 anotherPromise2
将同时拍摄
而示例 2:anotherPromise2
将等待 anotherPromise1
被解析
我不确定我是否理解这两种常见情况之间的区别。
假设我们有这个:
user.save().then(function(val){
anotherPromise1(val);
}).then(function(val){
anotherPromise2(val);
}).catch(function(err){
});
对比:
user.save().then(function(val){
return anotherPromise1(val);
}).then(function(val){
return anotherPromise2(val);
}).catch(function(err){
});
我知道这会有所不同,但具体情况如何?
如果您没有 return 来自 then
回调的值,您实际上是在 returning undefined
。下一个 then
回调将立即 运行,并将 undefined
视为分辨率值。
如果您 return 来自 then
回调的承诺,则第二个 then
回调会等待该承诺(间接地,但这并不重要),并且当promise 已解决,从该 promise 中获取分辨率值。
(这包含在 Promises/A+ spec 中的 then
规范中,但略有遗漏 — 它没有明确提及如果 onFulfilled
不 return 任何东西,但在 JavaScript 中,调用函数 总是 给你一个结果值;如果函数没有明确地 return 东西,undefined
是调用它的结果。Java脚本没有 void
方法的概念 a'la C/C#/C++/Java.)
你可以在这个脚本中看到它live copy on Babel's REPL:
let start = Date.now();
function elapsed() {
let rv = String(Date.now() - start);
while (rv.length < 4) {
rv = "0" + rv;
}
return rv;
}
function anotherPromise(type, val) {
console.log(`${elapsed()}: anotherPromise[${type}] got ${val}`);
return new Promise(resolve => {
setTimeout(() => { resolve(val * 2); }, 1000);
});
}
function anotherPromise2(type, val) {
console.log(`${elapsed()}: anotherPromise2[${type}] got ${val}`);
return new Promise(resolve => {
setTimeout(() => { resolve(val * 3); }, 10);
});
}
let user = {
save: () => {
return new Promise(resolve => {
setTimeout(() => {
resolve(42);
}, 10);
});
}
}
// Without return
user.save().then(function(val){
anotherPromise("without", val);
}).then(function(val){
anotherPromise2("without", val);
}).then(function() {
console.log(`${elapsed()}: All done`);
}).catch(function(err){
});
user.save().then(function(val){
return anotherPromise("with", val);
}).then(function(val){
return anotherPromise2("with", val);
}).then(function() {
console.log(`${elapsed()}: All done`);
}).catch(function(err){
});
输出是(例如):
0015: anotherPromise[without] got 42 0017: anotherPromise2[without] got undefined 0018: All done 0020: anotherPromise[with] got 42 1021: anotherPromise2[with] got 84 1032: All done
注意 without a return 和 with a return:
之间的区别Without,
anotherPromise2
被立即调用(正如我们可以从经过的时间值中看到的那样)并收到undefined
.和,
anotherPromise2
等待anotherPromise
的解析发生,然后收到84
(anotherPromise
的分辨率值)
不同的是这件事的时机。
在示例 1 中,save
承诺已完成,anotherPromise1
将被调用,因为没有承诺 returned,anotherPromise2
将被调用立即地。
如果您 return anotherPromise1
函数的承诺,anotherPromise
的调用将在 anotherPromise1
被解析后发生。
因此示例 1:anotherPromise1
和 anotherPromise2
将同时拍摄
而示例 2:anotherPromise2
将等待 anotherPromise1
被解析