答应我在使用回调时返回一个挂起状态



我用回调测试fetch API,但我的函数返回"Promise State:Pending";,我不明白为什么:

async function getJson(url, callback) {
await fetch(url)
.then(async function(response) {
return await response.json()
})
.then(function(data) {
console.log(data)
callback(data)
})
}
let getData = {
getAll: async function() {
await getJson('js/getJson/data.json', function(data) {
console.log(data.photographers) //OK
let test = data.photographers
return test
})
}
}
console.log(getData.getAll()); //return promise pending

感谢

下面列出了异步和基于承诺的编程的一般建议。。。

getJson()应该是这样的:

function getJson(url, callback) {
return fetch(url).then(function(response) {
return response.json();
});
}

只需返回fetch()已经返回的promise-不要尝试转换为回调。将基于promise的接口转换为回调接口在编程可用性方面是倒退的。Promise比异步编程的普通回调更适合编程。

以下是getAll()如何使用它:

const getData = {
getAll: async function() {
const data = await getJson('js/getJson/data.json');
return data.photographers;
}
}

或者,同样好的(相当于上面的例子)是:

const getData = {
getAll: function() {
return getJson('js/getJson/data.json').then(data => {
return data.photographers;
});
}
}

当您对多个异步操作进行排序时,await具有显著的优势,但当只有一个异步操作时,通常并没有多大帮助。使用它并没有错,只是它并没有提供太多帮助。

以下是如何调用getAll():

getData.getAll().then(photographers => {
console.log(photographers);
}).catch(err => {
console.log(err);
});

一般建议和解释:

1.阅读并研究asyncawait如何与promise协同工作只有当你明白了这一点后才使用它,然后你只会在等待承诺时使用await。除非您正在等待promise,否则await不会有任何用处。因此,如果您正在等待函数调用,则该函数必须返回promise,并且当该函数中的异步操作完成时,必须连接该promise。

2.不要把简单的回电和承诺混为一谈如果您使用promise接口进行编程,请使用该promise-永远不要将其转换为纯回调。从函数中返回一个promise,并让调用者使用它。在发明promise的众多原因中,有了promise,非简单异步操作中的控制流就简单多了(尤其是异步错误处理和错误传播到更高级别)。

3.将普通回调转换为promise如果您遇到一个异步操作,而您希望在有其他基于promise的异步操作(如fetch())的世界中使用该操作,则将普通回调封装到promise接口中,这样您就只能将基于promise调用与其他基于promet的调用混合使用。可靠地编写代码要简单得多。

4.async函数总是返回一个promise这就是它们在Javascript内部构建的方式。因此,async函数的调用者总是返回一个promise作为返回值。该承诺最初将处于pending状态。它将在未来某个时候得到解决,promise的最终解决值将是从async函数的外部范围返回的任何值。如果async函数的外部作用域中没有return语句,那么解析的值将是undefined,就像两个"异步"函数一样。

5.调用方从具有.then()await的promise中获取解析值这是从承诺中获得解决价值的仅有两种方法。因此,任何想要从async函数返回某个值的调用方都需要使用.then()await来获取该值。

6.如果函数中有一个基于promise的操作,并且您希望从函数中返回它的解析值,那么只需从函数返回该promise即可这将允许调用者使用该promise来获取值。请参阅我上面的getJson()实现,了解它的简单程度

7.避免使用return await fn(),而是使用return fn()如果您正在使用return await fn(),那么您已经处于async函数中,因此该函数已经返回了promise。因此,避免使用额外的await,因为它没有任何用处,只使用return fn()。如果fn()返回一个值,该值将成为async函数返回的promise的解析值。如果fn()返回promise,那么该promise的已解析值将成为async函数返回的promise的解析值。

8.从.then()处理程序返回一个值将成为父promise的解析值在上面内部使用.then()的第二个getData()示例中,return data.photographers;语句将父promise的解析值设置为data.photographers。因此,getData()的任何调用者都会发现data.photographers变成了getData()返回的promise的解析值。

9.从.then()处理程序返回promise会将promise链接起来,并且您返回的promise的已解析值将成为父promise的解析值从本质上讲,从.then()返回promise会导致父promise等待新返回的promise解析,然后从新返回的promise中获取其解析值。您可以在getJson()函数中看到这一点,其中response.json()返回一个新的promise,解析为http请求的json解析体。该解析值将成为函数返回的promise的解析值。

10.当期望返回promise时,不要传递回调如果将回调传递给某个异步函数,那么该函数在大多数情况下都不会返回promise,因为现在许多异步API要么接受回调,要么返回promise。因此,当希望使用await时,请确保您正在等待的函数正在返回promise。如果有疑问,请看医生。如果文档不清楚,请查看函数本身的代码,或者运行一个实验来查看实际返回值。例如,如果不向大多数mongodb异步API传递回调,它们将返回promise,但如果传递回调,则不会返回promise。使用其中一个,而不是同时使用。

它很有效,尽管它不是我真正想要的。因为我认为我可以将函数之外的结果存储在一个变量中。但事实上,这似乎是不可能的。

所有这些都是因为我必须对我的训练进行评估。提取不是强制性的。

在我的代码的第一个版本中,我没有使用它。我只是通过将JSON加载到变量中并将其添加到脚本标记中来同步地执行类和函数。

然而,我想做一些测试,因为那时我必须使用设计模式工厂的方法。我刚刚测试了一下,它能和你的代码一起工作。谢谢你在这么晚的时候抽出时间回复我。

//我们实例化工厂let factory=新标识工厂getData.getAll().then(摄影师=>{let identity=摄影师console.log(标识);//我们在工厂里传递身份let newIdentity=factory.createIdentity(identity,'all')console.log(newIdentity);showIdentity(newIdentity)}).catch(错误=>{console.log(err);})

最新更新