Javascript 为什么我们不把承诺锁在彼此的心里?
在一个关于承诺的youtube教程视频中,我发现了以下代码:Javascript 为什么我们不把承诺锁在彼此的心里?,javascript,Javascript,在一个关于承诺的youtube教程视频中,我发现了以下代码: let cleanRoom = function() { return new Promise((resolve, reject) => { resolve(); }); }; let removeGarbage = function() { return new Promise((resolve, reject) => { resolve(); }); }; let winIcecre
let cleanRoom = function() {
return new Promise((resolve, reject) => {
resolve();
});
};
let removeGarbage = function() {
return new Promise((resolve, reject) => {
resolve();
});
};
let winIcecream = function() {
return new Promise((resolve, reject) => {
resolve();
});
};
cleanRoom().then(function(){
return removeGarbage();
}).then(function() {
return winIcecream();
}).then(function() {
console.log('finished');
})
为什么承诺没有像每一个承诺那样被束缚住。那么单词就在前一个承诺之后?我的意思是,为什么例如。那么不是紧跟在removeGarbage()
之后,而是紧跟在cleanRoom()之后。那么()
,winIcecream()
在解决removeGarbage
问题之后会运行呢?
我还需要键入return
声明上述代码中的每个承诺吗?如果是,为什么我需要这样做?使用实现处理程序(在您的示例中传递给然后的函数)的目的是等待承诺实现,然后再执行其他操作
该代码的目标(显然)是等待洁净室
承诺兑现,然后启动removeGarbage
过程,然后在兑现承诺后,启动winIcecream
过程。同样值得注意的是,如果cleanRoom
的承诺被拒绝而不是被履行,removeGarbage
根本不会发生,因为它在履行处理程序中,而不是拒绝处理程序中
如果您这样做:
cleanRoom().then(function() { /*...*/ });
removeGarbage().then(function() { /*...*/ });
winIcecream().then(function() { /*...*/ });
…所有三个进程都将立即启动并并行运行(只要它们建模的异步进程可以与其他JavaScript代码并行运行)。他们之间根本就没有协调
…在解析removeGarbage
承诺后,winIcecream()
将如何运行
然后
,捕获
,最后
创建并返回新承诺。这些承诺的履行或拒绝取决于他们被要求履行的承诺发生了什么,以及他们的处理者在履行或返回的承诺中发生了什么。例如:
doThis()
.then(function() { return doThat(); })
.then(function() { console.log("done"); });
让我们从doThis()
将承诺称为“承诺A”。调用然后
对其创建一个新的承诺(“承诺B”),该承诺将被拒绝(如果承诺a被拒绝),或者如果承诺a得到履行,将调用其处理程序。承诺B被解析为处理程序返回的任何内容。在上面的代码中,假设承诺A已实现,并且doThat()
返回一个承诺(“承诺C”)。现在,Promise B被解析为Promise C—Promise C发生的任何事情都会发生在Promise B上。如果Promise C得到满足,Promise B就得到满足,并调用带有控制台.log的第二个处理程序
这可能会有所帮助。您最初的问题可以通过将内容改写为可变作业来回答
我使用arrow函数语法隐式地返回这里的新表达式;如果您使用的是常规函数,那么是的,如果您想按顺序运行它们,您必须返回新的链式承诺
const-roomCleanedPromise=cleanRoom();
const roomCleanedAndGarbageTakenOutPromise=roomCleanedPromise.then(()=>removeGarbage());
const roomcleaned and garbagetakenoutandcecreamwon promise=roomcleaned and garbagetakenoutpromise.then(()=>winIcecream());
const finishedPromise=roomcleaned和garbagetakenoutandcecreamwon promise.then(()=>console.log('finished');
然而,使用更现代的async
/await
语法更容易编写—您提到的YouTube教程可能有点过时
异步函数cleanRoom(){
控制台日志(“清洁室”);
//这可以做其他异步的事情,或者只需要一段时间
return{room:'clean'};//仅演示返回值
}
异步函数removeGarbage(){
log('清除垃圾');
//这可以做其他异步的事情,或者只需要一段时间
返回{垃圾:'已删除'};
}
//为简洁起见,省略了第三个函数
异步函数doAllTheThings(){
const roomStatus=等待洁净室();
const garbageStatus=wait removeGarbage();
console.log('finished');
}
你的建议/想法我的意思是,例如,为什么。然后不是立即在removeGarbage()之后,而是在cleanRoom()之后。然后()
是错误的。
每个承诺(.then)都不会立即执行
你可以看看你的例子(我编辑了一点)
您应该进一步了解事件循环的工作原理。这是一个相当奇怪的例子。异步函数是否应该返回一个值?如果是这样,您可能希望创建一个变量并将其分配给承诺链。这样你就有了价值——事实上,我们只是尽量避免在不需要的地方使用它(否则它会导致一个金字塔式的厄运)。好吧,除非你先打扫房间把所有的垃圾都打包好,否则倒垃圾是没有用的?@AKX-没错。@bartekw2213-FWIW,我在新书的第8章详细介绍了承诺(请参阅我的个人资料中的链接)。我喜欢上面的变量名方法。它可以帮助人们更好地了解发生了什么。
const cleanRoom = () => new Promise((resolve, reject) => {
resolve();
});
const removeGarbage = () => new Promise((resolve, reject) => {
resolve();
});
const winIcecream = () => new Promise((resolve, reject) => {
resolve();
})
cleanRoom().then(function(){
console.log('second');
return removeGarbage();
}).then(function() {
return winIcecream();
}).then(function() {
console.log('finished');
})
console.log('first');