尝试从异步函数调用外部函数时未处理的承诺拒绝

编程入门 行业动态 更新时间:2024-10-10 02:16:09
本文介绍了尝试从异步函数调用外部函数时未处理的承诺拒绝的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

错误消息:

WARN Possible Unhandled Promise Rejection (id: 1): Error: INVALID_STATE_ERR send@localhost:8081/index.bundle?platform=android&dev=true&minify=false&app=com.dcgymappfrontend&modulesOnly=false&runModule=true:31745:26 initialiseWebsocket@localhost:8081/index.bundle?platform=android&dev=true&minify=false&app=com.dcgymappfrontend&modulesOnly=false&runModule=true:100544:21 loadUserData$@localhost:8081/index.bundle?platform=android&dev=true&minify=false&app=com.dcgymappfrontend&modulesOnly=false&runModule=true:100610:40 tryCatch@localhost:8081/index.bundle?platform=android&dev=true&minify=false&app=com.dcgymappfrontend&modulesOnly=false&runModule=true:7739:23 invoke@localhost:8081/index.bundle?platform=android&dev=true&minify=false&app=com.dcgymappfrontend&modulesOnly=false&runModule=true:7912:32 tryCatch@localhost:8081/index.bundle?platform=android&dev=true&minify=false&app=com.dcgymappfrontend&modulesOnly=false&runModule=true:7739:23 invoke@localhost:8081/index.bundle?platform=android&dev=true&minify=false&app=com.dcgymappfrontend&modulesOnly=false&runModule=true:7812:30 localhost:8081/index.bundle?platform=android&dev=true&minify=false&app=com.dcgymappfrontend&modulesOnly=false&runModule=true:7822:21 tryCallOne@localhost:8081/index.bundle?platform=android&dev=true&minify=false&app=com.dcgymappfrontend&modulesOnly=false&runModule=true:28596:16 localhost:8081/index.bundle?platform=android&dev=true&minify=false&app=com.dcgymappfrontend&modulesOnly=false&runModule=true:28697:27 _callTimer@localhost:8081/index.bundle?platform=android&dev=true&minify=false&app=com.dcgymappfrontend&modulesOnly=false&runModule=true:29113:17 _callImmediatesPass@localhost:8081/index.bundle?platform=android&dev=true&minify=false&app=com.dcgymappfrontend&modulesOnly=false&runModule=true:29152:17 callImmediates@localhost:8081/index.bundle?platform=android&dev=true&minify=false&app=com.dcgymappfrontend&modulesOnly=false&runModule=true:29370:33 __callImmediates@localhost:8081/index.bundle?platform=android&dev=true&minify=false&app=com.dcgymappfrontend&modulesOnly=false&runModule=true:3279:35 localhost:8081/index.bundle?platform=android&dev=true&minify=false&app=com.dcgymappfrontend&modulesOnly=false&runModule=true:3057:34 __guard@localhost:8081/index.bundle?platform=android&dev=true&minify=false&app=com.dcgymappfrontend&modulesOnly=false&runModule=true:3262:15 flushedQueue@localhost:8081/index.bundle?platform=android&dev=true&minify=false&app=com.dcgymappfrontend&modulesOnly=false&runModule=true:3056:21 flushedQueue@[native code] invokeCallbackAndReturnFlushedQueue@[native code]

被指责为问题的useEffect:

React.useEffect(() => { // Fetch the token from storage then navigate to our appropriate place const loadUserData = async () => { let userData; try { userData = await retrieveUserData(); } catch (e) {} if(userData){ dispatch({ type: 'RESTORE_USER_DATA', userData: userData }); getChatData(userData, setChats, dispatch); if(userData && !websocketInitialised){ console.log('web init called from *load user data*') setWebsocketInitialised(true) initialiseWebsocket(userData); } } else{ dispatch({ type: 'RESTORE_USER_DATA_FAILED'}); } }; loadUserData(); }, []);

InitialliseWebSocket函数

function initialiseWebsocket(userData){ console.log('sending websocket initialisation data.'); websocket.send(JSON.stringify({ 'action': 'init', 'data' : {'token': userData.token} })); }

上面使用的useState

const [websocketInitialised, setWebsocketInitialised] = React.useState(false); async function getChatData(userData, setChats, dispatch){ console.log("fetching chat data"); // if we fail to download chat data, pull the old one from FS const loadOldChatData = async () => { let chats; try { chats = await retrieveChats(); } catch (e) {} if(chats){ setChats(chats); console.log("loaded cached chat data") ; } else{ setChats([]); } }; const onSuccess = (response) => { if(response['chats']){ storeChats(response['chats']); setChats(response['chats']); console.log("chat data synced"); } else{ loadOldChatData(); } }; const onFailure = (response) => { loadOldChatData(); }; fetch(Settings.siteUrl + '/messenger/get_chats/', { method: "GET", headers: { "Content-type": "application/json; charset=UTF-8", "Authorization": "Token " + userData.token }, }) .then(response => response.json()) .then(response => {onSuccess(response)}) .catch(response => {onFailure(response)}) }

RetrieseUseData()很可能不是问题所在,因为这只是在我添加其他代码后才开始出现的。

我是不应该使用这样的状态,还是应该使用在函数上工作的异步键?我试过了,但还是有同样的问题。您可以在第4行中看到它提到‘InitialiseWebSocket’函数的错误。我猜这就是路线的原因。我认为解决方案将是它的某个异步版本...

推荐答案

此错误告诉我们您没有或忘记处理来自异步代码的错误。

我稍微补充了一下您的代码,如果您从console.log(error);收到任何错误消息,请告诉我

React.useEffect(() => { // Fetch the token from storage then navigate to our appropriate place (async () => { try { let userData = await retrieveUserData(); dispatch({ type: 'RESTORE_USER_DATA', userData }); await getChatData(userData, setChats, dispatch); if (websocketInitialised) return; console.log('web init called from *load user data*') setWebsocketInitialised(true) initialiseWebsocket(userData); } catch (error) { console.log(error); dispatch({ type: 'RESTORE_USER_DATA_FAILED' }); } })(); }, []);

您应该将getChatData重命名为setChatData,我也简化了这些代码...

async function getChatData(userData, setChats, _dispatch) { try { let response = await fetch(Settings.siteUrl + '/messenger/get_chats/', { method: "GET", headers: { "Content-type": "application/json; charset=UTF-8", "Authorization": "Token " + userData.token }, }), data = await response.json(), chats = data['chats']; if (!chats?.length) throw "empty chat data, pull the old one from FS"; storeChats(chats); setChats(chats); } catch (_) { // if we fail to download chat data, pull the old one from FS await retrieveChats() .then(chats => setChats(chats)) .catch(() => setChats([])) } }

我真的不太明白您在对异步内容做什么。

async/await只是语法糖,它允许您以同步方式使用异步操作,async/await的一些规则

  • 在Other中要使用await keyword,您需要async函数。
  • 只需添加async关键字
  • 即可使任意函数异步
  • 异步函数始终返回promise
  • 举个例子:

    let delay = (ms, msg, bool) => new Promise((res, rej) => setTimeout(!bool ? res : rej , ms,msg)); 这个帮助器函数创建了一个promise对于我们的示例,它接受3个参数,它以millisecond作为第一个参数,延迟时,第二个参数作为有效负载。3ndBoolean;如果为真,则它将拒绝。

    数据-lang="js"数据-隐藏="假"数据-控制台="真"数据-巴贝尔="假"> let delay = (ms, msg, bool) => new Promise((res, rej) => setTimeout(!bool ? res : rej, ms, msg)); let log = console.log; async function myAsyncFn() { let hello = await delay(100, "hello,"); let world = await delay(300, " world!"); // we use a symbol '@' to indicate that, its from `myAsyncFn` log("@" , hello + world, "printed from async operation"); } myAsyncFn(); log("As you can see that, this message print first"); // we are creating an async function and called immediately, In other to use `await keyword` (async () => { try { let resolved = await delay(300,"resolved"); console.log(">" , `it ${resolved}!`); // this will reject and catch via `try/catch` block; let _ = await delay(600, "Error", true); log("It will not print!"); // ... } catch (error) { log(">" , `we can catch "${error}" with try/catch, as like any sync code!`); } })()

    如您所见,使用async/await它看起来一切都是同步的,对吗?甚至所有东西都是异步执行的!

    只需使用await关键字即可同步所有异步操作。

    更多推荐

    尝试从异步函数调用外部函数时未处理的承诺拒绝

    本文发布于:2023-11-26 21:32:59,感谢您对本站的认可!
    本文链接:https://www.elefans.com/category/jswz/34/1635270.html
    版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
    本文标签:函数   未处理

    发布评论

    评论列表 (有 0 条评论)
    草根站长

    >www.elefans.com

    编程频道|电子爱好者 - 技术资讯及电子产品介绍!