Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.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_Ecmascript 6_Sequelize.js_Es6 Promise - Fatal编程技术网

Javascript 承诺并不像我期望的那样

Javascript 承诺并不像我期望的那样,javascript,ecmascript-6,sequelize.js,es6-promise,Javascript,Ecmascript 6,Sequelize.js,Es6 Promise,我使用Express进行路由,使用Sequelize进行数据库管理 app.get('/api/users/:username', (req, res) => { let username = req.params.username; findChattersPerRole() .then(chattersPerRole => { console.log('instakbot should\'ve been added by now...'); }

我使用Express进行路由,使用Sequelize进行数据库管理

app.get('/api/users/:username', (req, res) => {
  let username = req.params.username;
  findChattersPerRole()
    .then(chattersPerRole => {
      console.log('instakbot should\'ve been added by now...');
    });
});
函数findChattersPerRole返回一个对象,其中每个用户的用户名和角色都是另一个对象

const findChattersPerRole = () => {
  return fetch('https://tmi.twitch.tv/group/user/instak/chatters')
    .then(parseJSON)
    .then(r => {
      let chatters = r.chatters;
      let chattersPerRole = Object.keys(chatters).map(role => {
        return chatters[role].map(username => {
          console.log('findOrCreateViewer will be executed after this');
          findOrCreateViewer(username, role);
          return {
            username: username,
            role: role
          };
        });
      });
      return Promise.resolve(flattenDeep(chattersPerRole));
    }).catch(err => {
      console.log(`Error in fetch: ${err}`);
    });
};
问题是,在我的过程中,我希望
console.log('instakbot现在应该已经添加了…')将在查看器插入数据库后执行,因为在函数findChattersPerRole中,我已经使用函数findOrCreateViewer插入了查看器。我预计会发生这种情况,因为在我的路径中,当findChattersPerRole()被解析时,我会编写console.log

const findOrCreateViewer = (username, role) => {

  return Viewer.findOrCreate({
    where: {
      username
    },
    defaults: {
      instakluiten: 5,
      role
    }
  }).spread((unit, created) => {
    console.log('unit is: ', unit.dataValues.username);
    if(created){
      return `created is ${created}`;
    }else{
      return unit;
    }
  });

};
然而,在我的终端你可以看到,这不是它发生的方式。。。为什么我的承诺没有在预期的时间执行?
findOrCreateViewer(用户名、角色)之后返回{username:…}
在调用函数之后和插入任何数据之前立即发生。这也意味着
返回Promise.resolve(flattedeep(chattersPerRole))在插入任何数据之前发生,等等


您说过
findOrCreateViewer
返回一个承诺,因此您需要等待该承诺得到解决(即,等待数据插入后),然后再继续执行其他操作

您希望chattersPerRole
成为一个承诺数组,并且只有在所有承诺都得到解决后才能继续

这很容易通过
承诺实现。所有

const findChattersPerRole = () => {
  return fetch('https://tmi.twitch.tv/group/user/instak/chatters')
    .then(parseJSON)
    .then(r => {
      let chatters = r.chatters;
      let chattersPerRole = Object.keys(chatters).map(
        role => chatters[role].map(username => {
          console.log('findOrCreateViewer will be executed after this');
          return findOrCreateViewer(username, role).then(
            () => ({username, role})
          );
        });
      );
      return Promise.all(flattenDeep(chattersPerRole));
    }).catch(err => {
      console.log(`Error in fetch: ${err}`);
    });
};

现在,
findChartersErrorle
返回的承诺将在
findOrCreateViewer
返回的所有承诺得到解决后得到解决。
findOrCreateViewer(用户名、角色)之后的
返回{username:}
在调用函数之后和插入任何数据之前立即发生。这也意味着
返回Promise.resolve(flattedeep(chattersPerRole))在插入任何数据之前发生,等等


您说过
findOrCreateViewer
返回一个承诺,因此您需要等待该承诺得到解决(即,等待数据插入后),然后再继续执行其他操作

您希望chattersPerRole
成为一个承诺数组,并且只有在所有承诺都得到解决后才能继续

这很容易通过
承诺实现。所有

const findChattersPerRole = () => {
  return fetch('https://tmi.twitch.tv/group/user/instak/chatters')
    .then(parseJSON)
    .then(r => {
      let chatters = r.chatters;
      let chattersPerRole = Object.keys(chatters).map(
        role => chatters[role].map(username => {
          console.log('findOrCreateViewer will be executed after this');
          return findOrCreateViewer(username, role).then(
            () => ({username, role})
          );
        });
      );
      return Promise.all(flattenDeep(chattersPerRole));
    }).catch(err => {
      console.log(`Error in fetch: ${err}`);
    });
};

现在,
findChattersPerRole
返回的承诺将在
findOrCreateViewer
返回的所有承诺得到解决后得到解决。

承诺没有任何魔力。返回承诺并不意味着调用函数将被阻塞,而是意味着可以轻松地链接回调以处理结果。你需要使用

function findChattersPerRole() {
  return fetch('https://tmi.twitch.tv/group/user/instak/chatters')
    .then(parseJSON)
    .then(r => {
      let chatters = r.chatters;
      let chattersPerRole = Object.keys(chatters).map(role => {
        return chatters[role].map(username => {
          console.log('findOrCreateViewer will be executed after this');
          return findOrCreateViewer(username, role).then(() => {
//        ^^^^^^                                   ^^^^^
            return {
              username: username,
              role: role
            };
          });
        });
      });
      return Promise.all(flattenDeep(chattersPerRole));
//                   ^^^ get a promise for an array of results from an array of promises
    }).catch(err => {
      console.log(`Error in fetch: ${err}`);
    });
}

承诺没有魔力。返回承诺并不意味着调用函数将被阻塞,而是意味着可以轻松地链接回调以处理结果。你需要使用

function findChattersPerRole() {
  return fetch('https://tmi.twitch.tv/group/user/instak/chatters')
    .then(parseJSON)
    .then(r => {
      let chatters = r.chatters;
      let chattersPerRole = Object.keys(chatters).map(role => {
        return chatters[role].map(username => {
          console.log('findOrCreateViewer will be executed after this');
          return findOrCreateViewer(username, role).then(() => {
//        ^^^^^^                                   ^^^^^
            return {
              username: username,
              role: role
            };
          });
        });
      });
      return Promise.all(flattenDeep(chattersPerRole));
//                   ^^^ get a promise for an array of results from an array of promises
    }).catch(err => {
      console.log(`Error in fetch: ${err}`);
    });
}

findOrCreateViewer
似乎是异步的,所以您希望该函数返回一个承诺,并执行类似于
return promise.all(chattersPerRole)的操作其中
chattersPerRole
是一个承诺数组(由
return findOrCreateViewer(username,role)创建。然后(()=>({username,role}));
来自
.map
回调)。因此,我可以说的不是价差。然后(return Promise.resolve(unit));?我不知道
.spread
做什么。它是否回报了承诺?如果是,那么您可能不需要更改该函数,但您必须对返回值进行处理(如我的第一条注释所示)。目前您没有对它做任何操作:
findOrCreateViewer(用户名、角色).Yes spread返回一个承诺。哦,你在第一次编辑后就失去了我,我在这个问题上工作了这么久,我的头都痛了。在这种情况下,为什么仅仅调用findOrCreateViewer(…)是一件坏事,或者至少不是最好的决定?因为您没有使用返回的承诺执行任何操作,所以在继续执行其他操作之前,您不知道何时“完成”(即插入数据)。如果您依赖异步操作按顺序运行,则需要等待它们中的每一个都完成,这就是Promissions提供给您的。
findOrCreateViewer
似乎是异步的,因此您希望该函数返回Promission并执行类似于
return Promission.all(chattersPerRole)的操作其中
chattersPerRole
是一个承诺数组(由
return findOrCreateViewer(username,role)创建。然后(()=>({username,role}));
来自
.map
回调)。因此,我可以说的不是价差。然后(return Promise.resolve(unit));?我不知道
.spread
做什么。它是否回报了承诺?如果是,那么您可能不需要更改该函数,但您必须对返回值进行处理(如我的第一条注释所示)。目前您没有对它做任何操作:
findOrCreateViewer(用户名、角色).Yes spread返回一个承诺。哦,你在第一次编辑后就失去了我,我在这个问题上工作了这么久,我的头都痛了。在这种情况下,为什么仅仅调用findOrCreateViewer(…)是一件坏事,或者至少不是最好的决定?因为您没有使用返回的承诺执行任何操作,所以在继续执行其他操作之前,您不知道何时“完成”(即插入数据)。如果您依赖异步操作按顺序运行,那么您需要等待它们中的每一个都完成,这就是承诺给您的。感谢您花时间向我解释这一点,非常感谢。你能解释一下Promise.resolve和Promise.all的区别吗?我现在明白了。一切都是这样,但我想我已经有了。决心,而我显然不是。另外,
()=>({username,role})
是否是一种与返回{…}等价的ES6语法?我想是的,但我宁愿确定。谢谢你