我一直在使用Promises
和async/await
,它们几乎是同一件事吗?通常,我要做的就是兑现诺言并退还等。
function someFetchThatTakesTime(){
// Promisify the request.
return new Promise((resolve, reject) => {
if(allGood){
resolve();
}else{
reject();
});
}
然后我可以做:
someFetchThatTakesTime()
.then(console.log('all good.')
.catch(console.log('some error occured.');
或者我可以做:
async function wrapMyFetch() {
try {
// Make the async call.
data = await someFetchThatTakesTime();
return data;
} catch(err) {
// Propagate the exception up stream.
throw err;
}
}
(async () => {
let response = await wrapMyFetch();
// Do stuff with the response.
})();
我想,到目前为止还很清楚。
但是,最近我遇到了这样的情况:我的应用程序不在乎等待获取结果和更新数据容器等。假设有一个更大的循环可以无限运行,并且任何Promised
请求只会在应用程序运行时填补空白。
在那种情况下,我们真的不需要async/await
模式对吗?我们只想继续前进,只要它们准备好就位(或者在发生错误的情况下不行),石头就会掉在我们身后。
我想澄清一下:async/await
只会迫使事物线性运行,对吗?但是,如果我们不希望线性,并且可以接受生成的任务-Promises
-在我们恢复运行周期的某个时间在后台完成其任务,则不需要{{ 1}}模式?正确吗?
答案 0 :(得分:2)
我一直在使用Promises和async / await,它们几乎是同一回事吗?
嗯,async/await
是基于promise建立的有用的语法。 Async/await
依靠承诺才能工作。因此,我不太称呼它们相同,但是您可以使用await
和try/catch
包围的.then().catch()
来编写功能相同的代码。您可以使用。两种方法都依赖诺言。
但是,最近我遇到了这样的情况,我的应用程序不在乎等待获取结果和更新数据容器等。假设有一个更大的循环无限运行,并且所有承诺的请求都将被填充-在应用程序运行时填补空白。
在那种情况下,我们真的不需要异步/等待模式吗?我们只想继续前进,只要它们准备好就位,石头就会掉在我们后面。(如果发生错误,则不会)。
没有规则,呼叫者必须注意返回的诺言,或者必须等待其继续执行任务。因此,如果您想像您所说的那样“仅让石头掉入背景中”,而这对于您的应用程序来说是合适的,则可以采用这种方式进行编码。
这通常被称为“即发即弃”编码,您在其中开始一些异步操作,该操作将自行执行某些操作,并且您不需要注意何时完成或是否有错误,因为对调用代码没有影响。
但是,有一个规则,即您不能让承诺拒绝无法处理。因此,如果您要返回一个承诺,而调用方将不对其做任何事情,那么您必须确保所有拒绝都由操作本身(使用.catch()
)来处理,这样唯一的事情退还给您是一个坚定的承诺。即使您所做的只是注意到错误并且不采取任何措施,也必须抓住错误。
答案 1 :(得分:1)
async
/await
只会迫使事物线性运行,对吗?
不是全局的,不是。 await
在async
函数中创建代码,该代码用于等待传递给您的诺言付诸实施,但这只会影响您在其中使用的函数,而不会影响调用该函数的任何东西。
async
函数是用于编写返回承诺的函数的语法糖。 await
是用于兑现承诺的语法糖。它们在一起可以极大地简化使用Promise的方式(特别是通过使拒绝错误自动在调用树中传播)。
更具体地说,一个async
函数同步运行其代码,直到第一个await
或return
(或直到代码运行结束该函数的末尾)为止,此时它返回一个诺言。然后,它的逻辑等待诺言完成,然后继续下去。最终,它根据await
或return
修改的最后一个承诺(或者如果代码执行结束时使用undefined
履行的最后一个承诺)发生的承诺。
如果您不想等待诺言的兑现,则不必这样做,甚至不必使用async
函数。只是不要在上面使用await
。例如,假设我们有一个fetch
的包装器,它可以为我们获取JSON(并修复了API脚枪):
async function fetchJSON(...args) {
const response = await fetch(...args);
if (!response.ok) {
throw new Error("HTTP error " + response.status);
}
return response.json();
}
这里有一个async
函数,使用它进行初始查询以获取要提取的事物的列表,然后并行获取所有这些事物::
async function fetchList(listUrl) {
const list = await fetchJSON(listUrl);
return Promise.all(list.map(item => fetchJSON(itemUrl)));
}
请注意,fetchList
如何使用await
来等待要提取的事物列表,但是却不等待这些事物;它只是从Promise.all
返回其开始提取的项目列表的承诺。
还要注意await
中的fetchJSON
如何使fetchJSON
的逻辑等待fetch
的诺言得以解决,但没有除非呼叫者使用fetchJSON
,否则呼叫await
的呼叫者会等待。 fetchList
仅await
是第一个调用(获取列表),它不会等待列表中的项目。