在制作返回promise的异步函数时,在每个实现中我都看到了这种做法:
function asyncFunction() {
return new Promise((resolve,reject) => {
// the function code
if (condition) resolve()
else reject()
})
}
换句话说,executor函数中的函数代码是同步运行的,并且仅答应建立和回调调用是异步完成的。这对我来说是违反直觉的,因为当我想到一个异步函数时,我想到了一个函数,该函数在执行时立即返回并推迟其操作供以后使用。这是一个示例:
function asyncFunction() {
return new Promise((resolve,reject) => {
setTimeout(() => {
// the function code
if (condition) resolve()
else reject()
}, 0)
})
}
这意味着该函数的代码将在任务中执行,并且在返回的promise上注册的所有回调将作为微任务运行。该函数立即返回,并且不会使线程饿死。
我现在有几个问题。
答案 0 :(得分:1)
承诺是管理异步代码而不是使代码异步的工具。
您的第一个示例根本不应该使用promise。该函数所做的所有事情都是阻塞的。使用诺言只会增加复杂性。 (例外是如果您正在编写代码以匹配有时用于异步操作的接口)。
您的第二个示例也毫无意义(至少几乎总是如此)。添加了 just 超时,以使事件循环在函数外部继续进行,然后稍后再次接收。此 可能很有用(例如,允许浏览器在耗时之前重绘窗口),但是方法应该是:
…,而您的代码似乎正在扭转这种局面,从承诺开始,并试图证明其合理性。
如果您有一些耗时的代码要运行,并且不想让它阻塞主事件循环,那么您可能应该使用 worker ,以便它在另一个线程上运行。可能您将使用Promise处理该代码,将其结果发送回主事件循环。
答案 1 :(得分:0)
我想总结一下我从@Bergi和@Quentin的答案和评论中学到的知识。我现在的理解如下:
异步函数的特征仅在于它立即返回(可能不执行某些同步操作,这是无关紧要的),并且最重要的是,它以非阻塞方式等待返回用于通知的值结果准备就绪时,等待其通知的订阅者。此外,该功能执行的操作可能会通过以下方式执行:
setTimeout
推迟所有三个示例:
第一:
/**
Compute the result synchronously, return immediately, and resolve with a value later, calling the callback
*/
function first(cb) {
// synchronous code
value = 0;
setTimeout(() => cb(value), 0)
}
此示例的另一个示例:
/*
Immediately resolve the promise synchronously, and then call the callback with value
*/
function first(){
const value = 0;
return Promise.resolve(value);
}
first().then((value) => {})
第二:
function second() {
return Promise.resolve(
fetch('some url'))
.then(response => response.json())
}
第三:
/*
Return immediately, perform the function code later, and resolve with a value later
*/
function third() {
return new Promise((resolve,reject) => {
setTimeout(() => {
// the function code
if (condition) resolve()
else reject()
}, 0)
})
主要功能全部返回,将结果传递给回调或以非阻塞方式解决。
请随时纠正我,我会尽我所能来理解它。谢谢。