短篇小说:
谈到Promises/A +,拒绝承诺的正确方法是什么 - 抛出错误?但如果我错过了catch- 我的整个应用程序将会爆炸!
如何使用promisify它有什么好处(也许你需要阅读更长的版本)?
是.then(success, fail)真正的反模式,我应该使用.then(success).catch(error)?
更长的版本,被描述为现实生活中的问题(希望有人阅读):
我有一个使用Bluebird(A + Promise实现库)的库,用于从数据库中获取数据(谈论Sequelize).每个查询都返回一个结果,但有时候它是空的(试图选择一些东西,但没有任何查询).承诺进入result函数,因为没有错误的原因(没有结果不是错误).例:
Entity.find(1).then(function(result) {
// always ending here, despite result is {}
}).catch(function(error) {
// never ends here
});
Run Code Online (Sandbox Code Playgroud)
我想包装它并检查结果是否为空(在我的代码中无法检查到这一点).我这样做了:
function findFirst() {
return Entity.find(1).then(function(result) {
if (result) { // add proper checks if needed
return result; // will invoke the success function
} else {
// I WANT …Run Code Online (Sandbox Code Playgroud) 我正在编写一个JavaScript函数,它发出HTTP请求并返回结果的承诺(但这个问题同样适用于基于回调的实现).
如果我立即知道为函数提供的参数是无效的,那么函数应该是throw同步的,还是应该返回一个被拒绝的promise(或者,如果你愿意的话,调用一个Error实例的回调)?
异步函数应始终以异步方式运行,特别是对于错误条件,这有多重要?是否确定throw,如果你知道程序是不是一个合适的状态的异步操作继续进行?
例如:
function getUserById(userId, cb) {
if (userId !== parseInt(userId)) {
throw new Error('userId is not valid')
}
// make async call
}
// OR...
function getUserById(userId, cb) {
if (userId !== parseInt(userId)) {
return cb(new Error('userId is not valid'))
}
// make async call
}
Run Code Online (Sandbox Code Playgroud) 请考虑以下代码:
import redis = require('redis'); //Has ambient declaration from DT
import bluebird = require('bluebird'); //Has ambient declaration from DT
bluebird.promisifyAll((<any>redis).RedisClient.prototype);
bluebird.promisifyAll((<any>redis).Multi.prototype);
const client = redis.createClient();
client.getAsync('foo').then(function(res) {
console.log(res);
});
Run Code Online (Sandbox Code Playgroud)
getAsync将错误输出,因为它是在运行中创建的,并且未在任何.d.ts文件中定义.那么处理这个问题的正确方法是什么?
此外,即使我有.d.ts加载redis的文件,我还需要投redis以any用于promisifyAll.否则,它会溢出错误:
Property 'RedisClient' does not exist on type 'typeof "redis"'
Run Code Online (Sandbox Code Playgroud)
输入它any是唯一容易的方法吗?
我承诺很多困惑.这是同步还是异步?
return new Promise (function(resolved,reject){
//sync or async?
});
Run Code Online (Sandbox Code Playgroud) 我想用来$q.when()包装一些非承诺的回调.但是,我无法弄清楚如何在回调中解决承诺.我在匿名函数内部做什么强迫$q.when()我解释?
promises = $q.when(
notAPromise(
// this resolves the promise, but does not pass the return value vvv
function success(res) { return "Special reason"; },
function failure(res) { return $q.reject('failure'); }
)
);
promises.then(
// I want success == "Special reason" from ^^^
function(success){ console.log("Success: " + success); },
function(failure){ console.log("I can reject easily enough"); }
);
Run Code Online (Sandbox Code Playgroud)
我想复制的功能是这样的:
promises = function(){
var deferred = $q.defer();
notAPromise(
function success(res) { deferred.resolve("Special reason"); },
function failure(res) { deferred.reject('failure'); …Run Code Online (Sandbox Code Playgroud) 如何使用Bluebird中的Promise包装Node.js回调?这就是我想出来的,但想知道是否有更好的方法:
return new Promise(function(onFulfilled, onRejected) {
nodeCall(function(err, res) {
if (err) {
onRejected(err);
}
onFulfilled(res);
});
});
Run Code Online (Sandbox Code Playgroud)
如果只需要返回错误,是否有更简洁的方法来执行此操作?
编辑 我试图使用Promise.promisifyAll(),但结果没有传播到then子句.我的具体示例如下所示.我正在使用两个库:a)sequelize,它返回promises,b)supertest(用于测试http请求),它使用节点样式回调.这是不使用promisifyAll的代码.它调用sequelize初始化数据库,然后发出HTTP请求来创建订单.正确打印Bosth console.log语句:
var request = require('supertest');
describe('Test', function() {
before(function(done) {
// Sync the database
sequelize.sync(
).then(function() {
console.log('Create an order');
request(app)
.post('/orders')
.send({
customer: 'John Smith'
})
.end(function(err, res) {
console.log('order:', res.body);
done();
});
});
});
...
});
Run Code Online (Sandbox Code Playgroud)
现在我尝试使用promisifyAll,以便我可以使用then链接调用:
var request = require('supertest');
Promise.promisifyAll(request.prototype);
describe('Test', function() {
before(function(done) {
// Sync the database
sequelize.sync(
).then(function() {
console.log('Create an order');
request(app) …Run Code Online (Sandbox Code Playgroud) 我正在尝试为上述问题编写代码.我试着寻找解决方案.这就是我现在拥有的.
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
var drawColorLine = function(start, end, color) {
var deltaX, deltaY, i = 0,
currLength = 0,
isHor, isVert;
deltaX = end[0] - start[0];
deltaY = end[1] - start[1];
context.strokeStyle = color;
isHor = deltaX === 0 ? 0 : 1;
isVert = deltaY === 0 ? 0 : 1;
function draw() {
context.beginPath();
context.moveTo(start[0] + currLength * isHor, start[1] + currLength * isVert);
currLength = currLength + 0.5 * i;
context.lineTo(start[0] …Run Code Online (Sandbox Code Playgroud)我想要完成的事情:
我得到了什么:
我正在使用Node和mysql.要插入关系,我必须等待艺术家插入或创建.我尝试使用以下代码完成:
let promises = [];
if (artists.length != 0) {
for (key in artists) {
promises.push( find_artist_id_or_create_new_artist(artists[key]) )
}
}
await Promise.all(promises);
Run Code Online (Sandbox Code Playgroud)
返回一个id:
async function find_artist_id_or_create_new_artist(artist_name) {
return await find_artist_return_id(artist_name, create_artist_return_id)
}
Run Code Online (Sandbox Code Playgroud)
寻找艺术家:
async function find_artist_return_id(artist_name, callback) {
var sql = "SELECT * FROM `artists` WHERE `name` LIKE "+con.escape(artist_name)+" LIMIT 1;"
con.query(sql, (err,row) => {
if(err) throw err;
if (row.length == 0) {
return callback(artist_name)
} else {
return row[0].id
}
}); …Run Code Online (Sandbox Code Playgroud) 以下代码片段是否相同?
function doSomething() {
var defer = $q.defer();
foo().then(function() {
bar().then(function() {
defer.resolve();
});
});
return defer.promise;
}
Run Code Online (Sandbox Code Playgroud)
function doSomething() {
return foo().then(bar);
}
Run Code Online (Sandbox Code Playgroud) 我正在尝试编写一个将节点式回调函数转换为promises的简单函数,因此我可以将它们与async/await一起使用.
当前代码:
function toPromise(ctx, func, ...args) {
let newPromise;
args.push((err, res) => {
newPromise = new Promise((resolve, reject)=> {
if(err) reject(err);
else{
resolve(res)
};
});
});
func.apply(ctx, args);
return newPromise;
}
Run Code Online (Sandbox Code Playgroud)
示例用法:
const match = await toPromise(user, user.comparePassword, password);
//trying to avoid the following:
user.comparePassword(password, (err, res) => {
... });
Run Code Online (Sandbox Code Playgroud)
对于一些很棒的库来说,这可能没有任何意义,但我只是想把它编写为一个练习.
问题当然是匹配评估为未定义,显然在await语法行之后,promise得到解决.
知道如何解决这个问题吗?
javascript ×10
promise ×8
node.js ×5
asynchronous ×3
bluebird ×3
angularjs ×2
async-await ×2
api-design ×1
canvas ×1
es6-promise ×1
synchronous ×1
typescript ×1