Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 为什么我们不把承诺锁在彼此的心里?_Javascript - Fatal编程技术网

Javascript 为什么我们不把承诺锁在彼此的心里?

Javascript 为什么我们不把承诺锁在彼此的心里?,javascript,Javascript,在一个关于承诺的youtube教程视频中,我发现了以下代码: let cleanRoom = function() { return new Promise((resolve, reject) => { resolve(); }); }; let removeGarbage = function() { return new Promise((resolve, reject) => { resolve(); }); }; let winIcecre

在一个关于承诺的youtube教程视频中,我发现了以下代码:

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');