Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/460.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_Promise - Fatal编程技术网

Javascript 多重承诺-在哪里解决?

Javascript 多重承诺-在哪里解决?,javascript,promise,Javascript,Promise,我是新来的承诺者。 我使用的是nodejs promisify,因此我将以下内容声明为对Redis的承诺 const { promisify } = require('util'); const getAsync = promisify(client.get).bind(client); const hmsetAsync = promisify(client.hmset).bind(client); const hsetAsync = promisify(client.hset).bind(cl

我是新来的承诺者。

我使用的是nodejs promisify,因此我将以下内容声明为对Redis的承诺

const { promisify } = require('util');
const getAsync = promisify(client.get).bind(client);
const hmsetAsync = promisify(client.hmset).bind(client);
const hsetAsync = promisify(client.hset).bind(client);
const incrAsync = promisify(client.incr).bind(client);
const smembersAsync = promisify(client.smembers).bind(client);
const keysAsync = promisify(client.keys).bind(client);
const sismemberAsync = promisify(client.sismember).bind(client);
我有以下功能,但我不知道解决(消息)的正确位置

然后我试着像这样调用函数

tools.sendMessage(3, 4, 'Does this work?','text').then((result)=> {
  console.log('Send Message Result => ',result);
}).catch(err => { 
  console.log(err)
});
如果我将解析(消息)放在现在的位置,上面的承诺不会解析,“发送消息结果”根本不会显示

如果我把它放在承诺链之外,var消息将返回一个空对象{}

我的问题:由于我需要等待多个redis检查,因此需要多个promise调用的此类函数中的解析应该放在哪里


我有很多功能,需要我的ReRIS调用才能进行下一个动作。

< P>我可以考虑重构你的代码如下。如果需要在过渡
.then()
阶段捕获错误,请使用onrejected回调

function sendMessage(senderId = '', roomId = '', text = '', type='text') {
  return keysAsync('room-'+roomId)
         .then(value => value === '' ? Promise.reject('Room '+roomId+ ' does not exist.')
                                     : sismemberAsync('roomuser-'+roomId, senderId))
         .then(ismember => ismember === 0 ? Promise.reject('User ' + senderId + ' is not a member of room ' + roomId)
                                          : incrAsync('messageId'))
         .then(id => { var datetime =new Date();
                       hmsetAsync('messsage:'+id, 'id', id, 'roomId', roomId, 'senderId', senderId, "created", datetime, "text", text);
                       saddAsync('roommessages-'+roomId, id);
                       return { id: id, roomId: roomId, senderId: senderId, created: datetime, text: text };
                     })
         .then(message => doSomethingWith(message))
         .catch(errorHandler);
}
在上面的代码中,我将
new Date()
移动到下面实际使用的一个阶段,但是如果出于某种原因,您需要在原始
中使用
datetime
。然后()
阶段,如您的问题所示,您可以执行以下操作:

function sendMessage(senderId = '', roomId = '', text = '', type='text') {
  return keysAsync('room-'+roomId)
         .then(value => value === '' ? Promise.reject('Room '+roomId+ ' does not exist.')
                                     : sismemberAsync('roomuser-'+roomId, senderId))
         .then(ismember => ismember === 0 ? Promise.reject('User ' + senderId + ' is not a member of room ' + roomId)
                                          : Promise.all([incrAsync('messageId'), new Date()]))
         .then(([id, datetime]) => { hmsetAsync('messsage:'+id, 'id', id, 'roomId', roomId, 'senderId', senderId, "created", datetime, "text", text);
                                     saddAsync('roommessages-'+roomId, id);
                                     return { id: id, roomId: roomId, senderId: senderId, created: datetime, text: text };
                                   })
         .then(message => doSomethingWith(message))
         .catch(errorHandler);
}

您已经承诺了所有异步函数,为什么您需要一个新的承诺构造函数?我希望sendMessage是一个承诺,所以当我最终调用sendMessage时,它可以是一个承诺链?你看,我的代码里也有很多拒绝电话。你不应该在新的承诺中包装任何东西。只需将现有承诺链接在一起,并从链中返回承诺。在redis编码之前,实际上有一些代码要检查senderId、text、roomId是否包含非法字符并拒绝()它们。然后,只需在异步操作之前返回
promise.reject(…)
,以检查这些检查错误。你永远不需要把现有的承诺包装成另一个承诺。这被认为是一种反模式。那么sendMessage仍然是一种承诺吗?“我现在正在试密码。@有人说是的。如果未拒绝任何内容,则
sendMessage
将返回一个承诺,返回值为
doSomethingWith(message)
。您还可以考虑将<代码>新的数据()/代码>移动到一个级别。在它所在的位置,并将其传递给下一个
。这样就可以消除逐级数组的分解。我现在在hmsetAsync遇到了问题,在这里,id作为承诺传递,但它需要是字符串。@Someone Special Oops。。!我想,在下面移动
newdate()
也可以修复这个错误。我更正了代码。在第二个代码示例中,您有一个无效的分号和一些缺少的
function sendMessage(senderId = '', roomId = '', text = '', type='text') {
  return keysAsync('room-'+roomId)
         .then(value => value === '' ? Promise.reject('Room '+roomId+ ' does not exist.')
                                     : sismemberAsync('roomuser-'+roomId, senderId))
         .then(ismember => ismember === 0 ? Promise.reject('User ' + senderId + ' is not a member of room ' + roomId)
                                          : Promise.all([incrAsync('messageId'), new Date()]))
         .then(([id, datetime]) => { hmsetAsync('messsage:'+id, 'id', id, 'roomId', roomId, 'senderId', senderId, "created", datetime, "text", text);
                                     saddAsync('roommessages-'+roomId, id);
                                     return { id: id, roomId: roomId, senderId: senderId, created: datetime, text: text };
                                   })
         .then(message => doSomethingWith(message))
         .catch(errorHandler);
}