我在评论中说:
“在继续下一个任务之前,每个任务都要成功完成,这一点很重要”
上面的代码不是这样做的,除非doTask2和doTask3不执行任务,而是返回稍后调用时执行任务的函数。
您回答:
“上面的代码不是这样做的”——我认为是这样——这些方法中的每一个都返回一个承诺,当任务完成时,承诺就会实现。
这可能是你问题的基础。
then
和
catch
期望函数,而不是承诺。我所指的代码是:
server.doTask1()
.then(server.doTask2())
.then(server.doTask3())
.catch( ... handle the error )
当该代码运行时,会发生以下情况
同步地
:
-
server.doTask1
被调用,开始其工作并返回一个承诺(让我们称之为“p1”)
-
server.doTask2
被调用,开始其工作并返回一个承诺(“p2”)
-
然后
在“p1”上调用,传入“p2”;它返回一个promise(“p3”)
-
server.doTask3
被调用,开始其工作并返回一个承诺(“p4”)
-
然后
在“p3”上调用,传入“p4”;它返回一个promise(“p5”)
-
接住
在“p5”上调用(返回从未使用过的promise)
此时,由启动的任务
doTask
,
doTask2
和
doTask3
都是并行运行的;他们会兑现承诺,但任务之间没有强制要求。你可以在这里看到:
const start = Date.now();
const elapsed = () => String(Date.now() - start).padStart(4);
const log = msg => console.log(`[${elapsed()}] ${msg}`);
const server = {
doTask1() {
return new Promise(resolve => {
log("task1 started");
setTimeout(() => {
log("task1 complete");
resolve("result1");
}, 200);
});
},
doTask2() {
return new Promise(resolve => {
log("task2 started");
setTimeout(() => {
log("task2 complete");
resolve("result2");
}, 300);
});
},
doTask3() {
return new Promise(resolve => {
log("task3 started");
setTimeout(() => {
log("task3 complete");
resolve("result3");
}, 100);
});
},
};
log("Running the code");
server.doTask1()
.then(server.doTask2())
.then(server.doTask3())
.catch(() => log(`ERROR: ${error}`))
.then(() => log("Chain complete"));
log("Done running the code");
.as-console-wrapper {
max-height: 100% !important;
}
注意任务1-3全部
开始
马上
要使它们一个接一个地运行,您需要将一个函数而不是promise传递到
then
:
server.doTask1()
.then(() => server.doTask2())
// ^^^^^^
.then(() => server.doTask3())
// ^^^^^^
.catch( ... handle the error )
我在这里做了两个假设:
-
重要的是什么
this
doTask2
和
doTask3
用调用
-
您不希望将上一个任务的结果传递给下一个任务。
如果其中一种或两种都不是真的,你还可以用其他方法来写。
现场示例:
const start = Date.now();
const elapsed = () => String(Date.now() - start).padStart(4);
const log = msg => console.log(`[${elapsed()}] ${msg}`);
const server = {
doTask1() {
return new Promise(resolve => {
log("task1 started");
setTimeout(() => {
log("task1 complete");
resolve("result1");
}, 200);
});
},
doTask2() {
return new Promise(resolve => {
log("task2 started");
setTimeout(() => {
log("task2 complete");
resolve("result2");
}, 300);
});
},
doTask3() {
return new Promise(resolve => {
log("task3 started");
setTimeout(() => {
log("task3 complete");
resolve("result3");
}, 100);
});
},
};
log("Running the code");
server.doTask1()
.then(() => server.doTask2())
.then(() => server.doTask3())
.catch(() => log(`ERROR: ${error}`))
.then(() => log("Chain complete"));
log("Done running the code");
.作为控制台包装器{
最大高度:100%!重要的
}
或者,在
async
作用
try {
await server.doTask1();
await server.doTask2();
await server.doTask3();
// ...
} catch (error) {
// ...handle/report error...
}
现场示例:
const start = Date.now();
const elapsed = () => String(Date.now() - start).padStart(4);
const log = msg => console.log(`[${elapsed()}] ${msg}`);
const server = {
doTask1() {
return new Promise(resolve => {
log("task1 started");
setTimeout(() => {
log("task1 complete");
resolve("result1");
}, 200);
});
},
doTask2() {
return new Promise(resolve => {
log("task2 started");
setTimeout(() => {
log("task2 complete");
resolve("result2");
}, 300);
});
},
doTask3() {
return new Promise(resolve => {
log("task3 started");
setTimeout(() => {
log("task3 complete");
resolve("result3");
}, 100);
});
},
};
(async () => {
try {
await server.doTask1();
await server.doTask2();
await server.doTask3();
// ...
log("Chain complete");
} catch (error) {
// ...handle/report error...
log(`ERROR: ${error}`);
}
})();
.作为控制台包装器{
最大高度:100%!重要的
}
笔记
有些非标准库在调用之前不会启动所承诺的异步工作
然后
兑现承诺。这些都是异常值。在正常情况下,promise是工作的完成标记
已经在进行中
(就是这样
异步
函数行为)。