Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/420.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 异步/等待不等待承诺解决_Javascript_Reactjs_Asynchronous_Redux - Fatal编程技术网

Javascript 异步/等待不等待承诺解决

Javascript 异步/等待不等待承诺解决,javascript,reactjs,asynchronous,redux,Javascript,Reactjs,Asynchronous,Redux,看来我对await的使用并不像我理解的那样 我认为async函数和await关键字可以用于返回承诺的调用(例如navigator.mediaDevices.getUserMedia),它会暂停函数执行(就像生成器函数一样),直到承诺得到解决,然后继续使用该函数 尽管我在等待电话,但它马上就回来了,我的控制台日志也出现了问题。具体来说,控制台中以“reducer”开头的日志出现在以“getter”开头的日志之前,此时它应该是另一种方式/与堆栈跟踪的运行方式(我认为)相反 谁能告诉我这里发生了什么事

看来我对
await
的使用并不像我理解的那样

我认为
async
函数和
await
关键字可以用于返回承诺的调用(例如
navigator.mediaDevices.getUserMedia
),它会暂停函数执行(就像生成器函数一样),直到承诺得到解决,然后继续使用该函数

尽管我在等待电话,但它马上就回来了,我的控制台日志也出现了问题。具体来说,控制台中以“reducer”开头的日志出现在以“getter”开头的日志之前,此时它应该是另一种方式/与堆栈跟踪的运行方式(我认为)相反

谁能告诉我这里发生了什么事

异步助手函数获取程序:

const getLocalStream = async () => {
  try {
    const localStream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true });
    console.log('getter localStream', localStream);
    console.log('about to return')
    return localStream;
  }
  catch (err) {
    console.error(err);
  }
}

export default getLocalStream;
减速机/仓库:

import getLocalStream from './getLocalStream';

const reducer = (state = {}, action) => {
  switch (action.type) {
    case 'SEND_CALL': {
      const { id } = action;
      const localStream =  getLocalStream();
      console.log('reducer localStream', localStream);
      const call = state.peer.call(id, localStream);
      return { ...state, call };
    }
    default: 
      return state;
  }
};
控制台:

reducer localStream Promise {<pending>}
Uncaught TypeError: Failed to execute 'addStream' on 'RTCPeerConnection': parameter 1 is not of type 'MediaStream'
getter localStream MediaStream {id: "B6Foz1jheGvnMqjiqC4PFoOvUVahF04zigzm", active: true, onaddtrack: null, onremovetrack: null, onactive: null, …}
about to return
reducer localStream Promise{}
未捕获的TypeError:未能对“RTCPeerConnection”执行“addStream”:参数1不是“MediaStream”类型
getter localStream MediaStream{id:“B6Foz1jheGvnMqjiqC4PFoOvUVahF04zigzm”,活动:true,onaddtrack:null,onremovetrack:null,onactive:null,…}
即将返回

您需要等待对减速器中的
异步
函数的调用


现在,您可以调用它,但不要等待它完成。

您也需要在
reducer
函数中使用
async/wait
,否则
getLocalStream()
将只返回一个
promise
实例

这是因为根据

调用异步函数时,它返回一个承诺。当异步函数返回一个值时,将使用返回的值解析承诺。当异步函数抛出异常或某个值时,承诺将被抛出的值拒绝

异步函数可以包含一个等待表达式,用于暂停 执行异步函数并等待传递的承诺 解析,然后恢复异步函数的执行和 返回已解析的值

使用。由于减速器必须返回新状态,因此无法在减速器中执行异步操作

您可以在中间件中执行异步操作,因此您可以自己编写中间件或使用redux thunk

如果您分派的操作是函数,则thunk将使用
dispatch
getState
函数执行该函数

//create send call action
const createSendCall = id => 
  async dispatch => {
    const localStream =  await getLocalStream();
    console.log('reducer localStream', localStream);
    const call = state.peer.call(id, localStream);
    dispatch(createDoneSend(call));
  }
//create done send action
const createDoneSend = call => ({
  type:"DONE_SEND",
  call
})

//reducer, SEND_CALL never comes here because it's handled in middle ware
switch (action.type) {
  case 'DONE_SEND': {
    return { ...state, call:action.call };
  }
  default: 
    return state;
Thunk将简化需要调度多个操作的异步中间件或操作

redux是如何工作的以及中间件是如何工作的,解释了它调用reducer“applicationhandler函数”,因为我将它作为事件存储而不是特定于redux的


可以找到redux不接受承诺作为状态并在解析时设置状态的原因。当一个挂起的过滤器请求被来自用户的一个更新的请求替换时,挂起的过滤器将拒绝,这是应该发生的事情,但是redux如何知道承诺应该拒绝呢?因此,如果我们必须解决,那么我们如何告诉redux在旧的挂起请求解决时不要设置状态?这些问题基本上可以由减速器不返回承诺和中间处理来解决。

但我在等待解决它在<代码> GETLoalSoals中。因此,它应该等待promise解析为常规原语值,然后将该原语分配给
const localStream
,然后继续返回原语localStream。此外,我可以在reducer中等待,因为它不是异步函数,而将其设置为异步函数会阻止应用程序,因为应用商店的构造需要同步。reducer返回的将是新状态,您现在将新状态设置为状态承诺,而不是将其设置为状态。@Casey:您无法从异步中逃脱。使用
wait
使您自己的函数异步并返回承诺。为什么
getLocalStream
应该返回承诺?它应该等待
getUserMedia
返回的承诺得到解析,然后再返回?
async
函数始终将结果包装为
承诺。解析
减速机返回的将是新状态,现在将新状态设置为状态承诺,而不是将其设置为状态。它会暂停执行
getLocalStream
。它不会暂停调用方的执行(
reducer
)-它只是向它返回一个承诺。也许可以解释ES使用回调、承诺和异步等待语法的原因。小捣蛋鬼:在异步函数之外,wait实际上并不等待任何东西,异步函数立即返回一个承诺。谢谢你的回答。我在这个项目中使用
peerjs
,通过WebRTC处理P2P视频聊天。我试图将有关连接和视频通话的信息保存在redux应用商店中,以便在应用程序的不同组件中访问它。看来
peerjs
API是严格基于回调的(没有承诺API),在这种情况下我还能使用
redux-thunk
吗?@Casey-thunk不关心承诺或回调。您将函数作为acion分派,thunk将使用
dispatch
getState
运行该函数。函数中的操作取决于您自己,回调或承诺,没有异步代码,但调度多个操作,什么也不做,任何适合该操作的操作。这个答案包含一些将回调类型函数转换为返回承诺的函数的代码。包括一个上下文对象(这个值)也是如此。
//create send call action
const createSendCall = id => 
  async dispatch => {
    const localStream =  await getLocalStream();
    console.log('reducer localStream', localStream);
    const call = state.peer.call(id, localStream);
    dispatch(createDoneSend(call));
  }
//create done send action
const createDoneSend = call => ({
  type:"DONE_SEND",
  call
})

//reducer, SEND_CALL never comes here because it's handled in middle ware
switch (action.type) {
  case 'DONE_SEND': {
    return { ...state, call:action.call };
  }
  default: 
    return state;