我有以下代码:
authService.authenticate()
.then(function (user) {
return Task.all({user: user})
})
.then(function (tasks) {
// How to access user object here?
})
Run Code Online (Sandbox Code Playgroud)
是否有一些内置的方法将user对象传递给第二个then函数而不执行以下操作:
var user2 = null;
authService.authenticate()
.then(function (user) {
user2 = user
return Task.all({user: user})
})
.then(function (tasks) {
// Use user2 here
})
Run Code Online (Sandbox Code Playgroud)
或这个:
authService.authenticate()
.then(function (user) {
var defer = $q.defer()
Task.all({user: user}).then(function (tasks) {
return defer.resolve(user, tasks)
})
return defer.promise
})
.then(function (user, tasks) {
// Use user2 here
})
Run Code Online (Sandbox Code Playgroud)
或通过then直接调用第二个来嵌套它们 …
我已经阅读了几个使用JavaScript生成器的代码示例,例如这个.我能想到的最简单的生成器使用块是这样的:
function read(path) {
return function (done) {
fs.readFile(path, "file", done);
}
}
co(function *() {
console.log( yield read("file") );
})();
Run Code Online (Sandbox Code Playgroud)
这确实打印出了内容file,但我的挂断是在哪里done调用.看起来,yield是一个语法糖,用于包装它在回调中返回的内容并适当地分配结果值(至少在co将错误参数抛给回调的情况下).我对语法的理解是否正确?
使用done时看起来像什么yield?
我是Promises的新手,我想知道最佳做法是在保持变量的同时保持变量?
通过Promise连接到MongoDB非常简单:
connectToMongoDB(data).done(function(db) {
var collection = db.collection('test_inserts');
// do more stuff here
});
Run Code Online (Sandbox Code Playgroud)
但是,如果我必须连接到两个不同的数据库会发生什么?
connectToMongoDB1(data1).then(function(db1) {
return connectToMongoDB2(data2);
}).done(function(db2) {
var collection = db1.collection('test_inserts');
// ERROR: db1 is undefined
});
Run Code Online (Sandbox Code Playgroud)
这个错误非常有意义.但是如何在db1不改变我的connectToMongoDB2()功能的情况下前进,因为我想要保持connectToMongoDB2()并且我的所有承诺一般都非常通用?
我的意思是,我可以包装一个存储所有相关内容的对象,但这看起来有点像hacky:
var relevantStuff = {};
connectToMongoDB1(data1).then(function(db1) {
relevantStuff.db1 = db1;
return connectToMongoDB2(data2);
}).done(function(db2) {
var collection = relevantStuff.db1.collection('test_inserts');
// do more stuff here
});
Run Code Online (Sandbox Code Playgroud)
什么是最佳做法?
我想在一个bookhelf事务中更新许多数据库表.我可以使用一些帮助重构我的代码.我是节点的新手,对Promises没有很好的理解,但下面的嵌套结构不是很漂亮,我希望有一个更清洁的方法.任何帮助,将不胜感激.
function insertUser(user, cb) {
bookshelf.transaction(function(t) {
var key = user.key;
Developer.forge({key: key})
.fetch({require: true, transacting: t})
.then(function(developerModel) {
var devID = developerModel.get('id');
Address.forge(user.address)
.save(null, {transacting: t})
.then(function(addressModel) {
var addressID = addressModel.get('addressId');
Financial.forge(user.financial)
.save(null, {transacting: t})
.then(function(financialModel) {
var financialID = financialModel.get('financialId');
var userEntity = user.personal;
userEntity.addressId = addressID;
userEntity.developerId = devID;
userEntity.financialId = financialId;
User.forge(userEntity)
.save(null, {transacting: t})
.then(function(userModel) {
logger.info('saved user: ', userModel);
logger.info('commiting transaction');
t.commit(userModel);
})
.catch(function(err) {
logger.error('Error saving user: ', err);
t.rollback(err);
});
}) …Run Code Online (Sandbox Code Playgroud) 我正在编写一些node.js来通过串口连接与传感器进行交互.用于读取传感器的代码当然是异步的.但是,在我的控制代码中,我需要读取传感器,根据值执行某些操作,再次读取,执行其他操作等.为此,我使用的代码类似于以下自包含测试:
var main = new Main();
main.next();
function* Main()
{
var reading = yield readSensor(this.next.bind(this));
console.log(reading);
var reading = yield readSensor(this.next.bind(this));
console.log(reading);
}
function readSensor(callback)
{
// simulate asynchrounous callback from reading sensor
setTimeout(function sensorCallback() { callback('foo'); }, 100);
}
Run Code Online (Sandbox Code Playgroud)
所以,我的顺序控制代码在一个生成器中,readSensor()当它需要读取时产生.传感器读取完成后,它会调用回调,然后控制返回主代码.我这样做是因为我可能需要根据之前的读数以不同的顺序读取各种传感器.所以,这是一个值得怀疑的部分:我this.next.bind(this)作为回调函数传递给异步读取函数.当启用生成器(--harmony_generators)时,代码似乎工作,但我想知道这里是否存在我遗漏的陷阱.我对JS比较新,所以不要害怕指出明显的:)
我想确保我没有错过任何一个技巧;在 Kris Kowal 的库中,您可以执行以下操作作为 Promise 中的通用 catch 语句:
var a, b, c, d, e, f;
readFile('fileA')
.then(function (res) {
a = res;
return readFile('fileB');
})
.then(function (res) {
b = res;
return readFile('fileC');
})
.then(function (res) {
c = res;
return readFile('fileD');
})
.then(function (res) {
d = res;
return readFile('fileE');
})
.then(function (res) {
e = res;
return readFile('fileF');
})
.then(function () {
f = res;
})
.catch(function () {
// error happened in file read *somewhere* (don't care …Run Code Online (Sandbox Code Playgroud) 这是我使用await / async的漂亮代码
monthlyBuckets(req, res) {
const monthlyBuckets = []
const now = DateTime.local()
let date = config.beginningOfTime
while (date < now) {
monthlyBuckets.push({
epoch: date.toMillis(),
month: date.month,
year: date.year,
actions: await redis.get(`actions_monthly_${date.year}_${date.month}`),
interested: await redis.scard(`sinterested_monthly_${date.year}_${date.month}`),
adventurous: await redis.scard(`sadventurous_monthly_${date.year}_${date.month}`),
active: await redis.scard(`sactive_monthly_${date.year}_${date.month}`),
})
date = date.plus({month: 1})
}
res.status(200).json(monthlyBuckets)
}
Run Code Online (Sandbox Code Playgroud)
我喜欢它,但是不并行执行这么多请求会导致请求时间接近3秒。
因此,这是我没有异步/等待的丑陋解决方案,只是承诺:
monthlyBuckets(req, res) {
const monthlyBuckets = []
const actions = []
const interested = []
const adventurous = []
const active = []
const now = DateTime.local()
let …Run Code Online (Sandbox Code Playgroud) 我的画布尺寸和位置未知.我想基于量角器中画布的尺寸和位置来模拟单击特定坐标.
以下工作,但相当繁琐:
var canvas = element(by.id("canvas"));
canvas.getCssValue("left").then(function (left) {
canvas.getCssValue("top").then(function (top) {
canvas.getCssValue("width").then(function(oldWidth) {
canvas.getCssValue("height").then(function (oldHeight) {
// some code that uses left, top, oldWidth and oldHeight together
})
})
})
}
)
})
})
Run Code Online (Sandbox Code Playgroud)
是否有更优雅的方式一次性使用所有这些承诺?我真的想做类似以下的事情:
var width = canvas.getCssValue("width");
var height = canvas.getCssValue("height");
var left = canvas.getCssValue("left");
var top = canvas.getCssValue("top");
//code that uses these variables.
Run Code Online (Sandbox Code Playgroud)
但当然,如果违背承诺的性质.谢谢你的帮助.
我需要通过promise .then链传递一个变量.我找不到办法解决问题.我对此很陌生,所以请耐心等待!
return foo.bar(baz)
.then((firstResult) => {
let message = firstResult;
})
.then(() => foo.bar(qux)
.then((secondResult) => {
message =+ secondResult;
console.log(message);
})
)
Run Code Online (Sandbox Code Playgroud)
这样做的正确方法是什么?
我正在阅读几篇文章并观看有关如何在 JavaScript 中使用 async/await 的一些视频,似乎唯一的原因是在同步代码中转换异步代码(并使代码更具可读性,但这不打算在此问题中讨论)。
所以,我想了解使用这些语句是否有更多原因,因为在我的理解中,如果我们有 Promises 来进行异步调用并提高我们代码的性能,为什么我们要再次将其转换为同步代码?
javascript ×9
promise ×6
node.js ×4
angularjs ×2
async-await ×2
yield ×2
asynchronous ×1
bookshelf.js ×1
co ×1
deferred ×1
es6-promise ×1
generator ×1
jquery ×1
nested ×1
protractor ×1
variables ×1