使用promise确实可以避免邪恶金字塔,但是……
发布于 3 年前 作者 itcaptainli 2935 次浏览 来自 问答

用promise,确实可以解决邪恶金字塔。 但是…… 如果将此用在数据库查询上,select到的数据,想输出到网页上。不管是send()还是rander(),都只能写一个,否则就会报header错误。 将不同的查询写在不同的.then中,后面的then也没办法读取前面的then里读取到的sql数据呀。 因此还是得用邪恶金字塔…… 那么问题来了,各位仁兄,有什么办法,能让下一个回调读取到上一个回调得到的数据么。

13 回复

.then()其实也是可以读到上一个.then()的数据,把异步获得的数据放在回调函数里面传入即可,只是层次多了还是很麻烦。还有一些库可以简化操作,如果想要爽一点,就用async/await

@huguangju 你发了个啥……

@nullcc 具体肿么弄,有木有例子? 比如下面这个 .then(function(data2){ db.query(‘select * from zm_article_menu’, function(err, data){ if(err){ console.log(err); }else{ for(var i=0; i<data.length; i++){ arr2.push(data[i][‘menuTitle’]); }; }; }); })

cnodejs 有 bug。点工具栏上的链接图标添加 url 时被加成了图片(前面多加了个!号)

@itcaptainli try this

.then(function(data2) {
  return new Promise(function (resolve, reject) {
	db.query(‘select * from zm_article_menu’, function(err, data) {
	  if (err) {
		console.log(err);
	  } else {
		for (var i = 0; i < data.length; i++) {
		  arr2.push(data[i][‘menuTitle’]);
		};
	  };
	  return resolve([data2, arr2]);
	});
  });
});

@Rukeith 那下一个then,如何接收这个then传的参数啊

@Rukeith 会用了,3Q

@huguangju 多谢,会用了

邪恶金字塔 哈哈

@itcaptainli promise 的强大远非于此的 你的问题可以定义公共变量

const data = []
.then((data1) => {
     data.push(data1)
	 return db.query(‘select * from zm_article_menu’)
	 // 大多数驱动应该都提供 promise 吧,如果没提供
	 // require('bluebird').promisify(db.query)
})
.then((data2) => {
     /*
	  接收上次查询结果,只要上次返回的是一个 promise 工厂函数,那么就能正确顺序执行,否则会导致下一次 then 和这次 then 中的动作同时执行,promise 工厂函数形如
	  function(args){
	     return new Promise((resolve,reject) => {
		    // async task
		 })
	  }
	*/ 
})		

promise是传染的

楼上说的 promise 把结果传给下一个then 是可以的,但如果多个查询没有互相影响的话还是建议使用 Promise.all() 方法

const sql1 = db.query('select * from table1')
const sql2 = db.query('select * from table2')
Promise.all([sql1, sql2]).then(([data1, data2])=>{
	// res.json({
	// data1,
	// data2,
	// )
}).catch(e=>{})
回到顶部