gpt4 book ai didi

node.js - 我应该如何在 Node js 中使用 Promise 进行 db + http 调用

转载 作者:太空宇宙 更新时间:2023-11-04 00:24:08 25 4
gpt4 key购买 nike

我需要实现系统

  • 从父集合中获取数据。
  • 检查redis中是否找到特定键
  • 如果没有,则进行 http 调用并获取 json 数据,然后设置缓存
  • 如果是,则从缓存中获取数据
  • 将数据保存到父 ID 的子集合中。

我有使用类似回调的工作解决方案。

MongoClient.connect(dsn).then(function(db) {
parentcollection.findOne({"_id" : new ObjectId(pid)}, function(err, data) {

var redis = require("redis"),
client = redis.createClient();

client.on("error", function (err) {
console.log("Error " + err);
});

// If not set

client.get(cacheKey, function(err, data) {
// data is null if the key doesn't exist
if(err || data === null) {
var options = {
host: HOST,
port: 80,
path: URI
};

var req = http.get(options, function(res) {
res.setEncoding('utf8');
res.on('data', function (chunk) {
body += chunk;
//console.log('CHUNK: ' + chunk);
});
res.on('end', function () {
data = JSON.parse(body);


// Get childdata After process of data

childcollection.save(childdata, {w:1}, function(cerr, inserted) {
db.close();

});
});
});
} else {
// Get childdata from cache data
childcollection.save(childdata, {w:1}, function(cerr, inserted) {
db.close();
});
}
});
});

我想使用 Promise(原生的,而不是像 bluebird/request 这样的外部的)而不是回调。我查看手册并思考是否需要这样实现

var promise1 = new Promise((resolve, reject) => {

MongoClient.connect(dsn).then(function(db) {
parentcollection.findOne({"_id" : new ObjectId(pid)}, function(err, data) {


});

}}.then(function(data){
var promise2 = new Promise((resolve, reject) => {
var redis = require("redis"),
client = redis.createClient();

client.on("error", function (err) {
console.log("Error " + err);
});

// If not set

client.get(cacheKey, function(err, data) {
// data is null if the key doesn't exist
if(err || data === null) {
var options = {
host: HOST,
port: 80,
path: URI
};

var promise3 = new Promise((resolve, reject) => {
var req = http.get(options, function(res) {
res.setEncoding('utf8');
res.on('data', function (chunk) {
body += chunk;
//console.log('CHUNK: ' + chunk);
});
res.on('end', function () {
data = JSON.parse(body);


// Get childdata After process of data


});
})
}).then(function(data){
childcollection.save(childdata, {w:1}, function(cerr, inserted) {
db.close();

});
});
} else {
// Get childdata from cache data
childcollection.save(childdata, {w:1}, function(cerr, inserted) {
db.close();
});
}
});

}}.then(function(data){
});
});

哪个看起来像回调 hell 一样肮脏,还是有任何更好的方法不使用上面的 promise ?

最佳答案

一个问题是您永远不会调用提供给 Promise 构造函数回调的 resolve 函数。如果不调用他们, promise 永远不会兑现。

我建议在单独的、可重用的函数中创建这些新的 promise 。另一方面,当您不提供回调参数时,某些 MongoDb 方法已经返回 Promise。

你可以像下面这样做。

// Two promisifying functions:
function promiseClientData(client, key) {
return new Promise(function (resolve, reject) {
return client.get(key, function (err, data) {
return err ? reject(err) : resolve(data); // fulfull the promise
});
});
}

function promiseHttpData(options) {
return new Promise(function (resolve, reject) {
return http.get(options, function(res) {
var body = ''; // You need to initialise this...
res.setEncoding('utf8');
res.on('data', function (chunk) {
body += chunk;
//console.log('CHUNK: ' + chunk);
});
res.on('end', function () {
data = JSON.parse(body);
resolve(data); // fulfull the promise
});
);
});
}

// Declare the db variable outside of the promise chain to avoid
// having to pass it through
var db;

// The actual promise chain:
MongoClient.connect(dsn).then(function (dbArg) {
db = dbArg;
return parentcollection.findOne({"_id" : new ObjectId(pid)}); // returns a promise
}).then(function (data) {
var redis = require("redis"),
client = redis.createClient();
client.on("error", function (err) {
console.log("Error " + err);
});
// Get somehow cacheKey...
// ...
return promiseClientData(client, cacheKey);
}).then(function (data) {
// If not set: data is null if the key doesn't exist
// Throwing an error will trigger the next `catch` callback
if(data === null) throw "key does not exist";
return data;
}).catch(function (err) {
var options = {
host: HOST,
port: 80,
path: URI
};
return promiseHttpData(options);
}).then(function (data) {
// Get childdata by processing data (in either case)
// ....
// ....
return childcollection.save(childdata, {w:1}); // returns a promise
}).then(function () {
db.close();
});

我认为 MongoDb 返回的 promise 是完全合规的。如果有疑问,您可以通过对它们调用 Promise.resolve() 将它们转换为原生 JavaScript promise ,例如如下所示:

return Promise.resolve(parentcollection.findOne({"_id" : new ObjectId(pid)}));

或者:

return Promise.resolve(childcollection.save(childdata, {w:1}));

关于node.js - 我应该如何在 Node js 中使用 Promise 进行 db + http 调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43496725/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com