gpt4 book ai didi

javascript - JS Promise - 立即从返回 Promise 的函数中检索一些数据

转载 作者:数据小太阳 更新时间:2023-10-29 03:51:08 25 4
gpt4 key购买 nike

谁能推荐一种模式来立即从返回 Promise 的函数中检索数据?

我的(简化的)示例是一个 AJAX 预加载器:

loadPage("index.html").then(displayPage);

如果这是下载一个大页面,我希望能够检查发生了什么,并可能在稍后阶段使用 XHR abort() 取消该过程。

我的 loadPage 函数过去常常(在 Promises 之前)返回一个 id,让我稍后执行此操作:

var loadPageId = loadPage("index.html",displayPage);
...
doSomething(loadPageId);
cancelLoadPage(loadPageId);

在我基于 Promise 的新版本中,我想象 cancelLoadPage() 会拒绝 () 原始的 loadPage() Promise。

我考虑了一些我不喜欢的选项。是否有普遍接受的方法来实现这一目标?

最佳答案

好的,让我们先解决您的赏金问题。

[Hopefully I'll be able to grant the points to someone who says more than "Don't use promises"... ]

抱歉,这里的答案是:“不要使用 promise ”。 ES6 Promises 具有三种可能的状态(对您作为用户而言):待处理、已解决和已拒绝(名称可能略有不同)。

您无法查看 promise 的“内部”以了解已完成的内容和未完成的内容 - 至少对于原生 ES6 promise 而言是这样。 There was some limited work (在其他框架中)在 promise 通知上完成,但那些并没有进入 ES6 规范,所以即使你找到了它的实现,你使用它也是不明智的。

Promise 代表 future 某个时刻的异步操作;独立的,它不适合这个目的。您想要的可能更类似于事件发布者 - 甚至是异步的,而不是同步的。

没有安全的方法可以让您同步从异步调用中获取一些值,尤其是在 JavaScript 中。造成这种情况的主要原因之一是,一个好的 API,如果它可以是异步的,那么它将始终是异步的。

考虑以下示例:

const promiseValue = Promise.resolve(5)
promiseValue.then((value) => console.log(value))
console.log('test')

现在,让我们假设这个 promise (因为我们提前知道值)是同步解决的。你希望看到什么?您希望看到:

> 5
> test

然而,实际发生的是这样的:

> test
> 5

这是因为即使 Promise.resolve() 是一个同步调用来解决一个已经解决的 Promise,then() 总是 是异步的;这是规范的保证之一,而且是一个非常好的保证,因为它使代码更容易推理 - 想象一下如果您尝试混合使用同步和异步 promise 会发生什么。

顺便说一下,这适用于所有异步调用:JavaScript 中任何可能是异步的操作都将是异步的。因此,您无法在 JavaScript 提供的任何 API 中进行任何类型的同步内省(introspection)。

这并不是说您不能对请求对象进行某种包装,如下所示:

function makeRequest(url) {
const requestObject = new XMLHttpRequest()
const result = {

}

result.done = new Promise((resolve, reject) => {
requestObject.onreadystatechange = function() {
..
}
})
requestObject.open(url)
requestObject.send()
return requestObject
}

但这会变得非常困惑,速度非常快,您仍然需要使用某种异步回调才能使其正常工作。当您尝试使用 Fetch 时,这一切都会失败。另请注意,Promise 取消目前不是规范的一部分。参见 here有关该特定位的更多信息。

TL:DR:同步内省(introspection)在 JavaScript 中的任何异步操作都是不可能的,即使您尝试使用 Promise 也不是可行的方法。例如,您无法同步显示有关正在进行的请求的信息。在其他语言中,尝试这样做将需要阻塞或竞争条件。

关于javascript - JS Promise - 立即从返回 Promise 的函数中检索一些数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39140670/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com