我有一个函数,它返回一个javascript Promise,并在其中运行一些异步代码.异步代码需要在失败的情况下重试几次.我这样做,直到我观察到一些奇怪的行为让我想知道我是否正确行事.所以我不得不改变它.这两种方法都在这里.我知道为什么第一种方法(asyncFunc)不起作用,如果有人可以分享一些技术清晰度,我将不胜感激.对于第二种方法(ayncFunc_newer)有关如何更好地完成任何建议吗?
var _retryCount = 0;
// this is what I was doing
function asyncFunc () {
return new Promise(function(fulfill, reject) {
doAsync()
.then(fulfill)
.catch(retry);
function retry(promiseResult) {
if(_retryCount < 3) {
_retryCount++;
return asyncFunc();
}
else {
reject(promiseResult);
}
}
});
}
// this what I'm doing now
function ayncFunc_newer() {
return new Promise(function(fulfill, reject) {
var retryCount = 0;
doAsync()
.then(fulfill)
.catch(onReject);
function onReject(bmAuthError) {
if(retryCount < 3) {
retryCount++;
logWarning(error);
doAsync()
.then(fulfill)
.catch(onReject);
}
else {
fulfill(false); …Run Code Online (Sandbox Code Playgroud)我正在尝试使用Node和Bluebird(promises库)递归迭代一个给定的目录,但只要看起来它不能正常工作.
当我取消注释下面的'console.log'行时,似乎我得到了正确的结果,但我不确定是怎么回事,因为我从下面的消费代码得到的最终结果只是第一个文件第一个目录.
也许问题不在于迭代函数本身,而在于我正在消费它的方式.
我对承诺有点新意,所以也许我只是以错误的方式接近它.
这是我写的代码.
import * as Path from "path";
import * as Promise from "bluebird";
const FS: any = Promise.promisifyAll<any>((require("fs")));
export class Dir {
public static iterate(path: string) {
return new Promise((resolve, reject) => {
FS.lstatAsync(path).then(stat => {
if (stat.isDirectory()) {
FS.readdirAsync(path).each(name => {
let fullPath = Path.join(path, name);
// console.log(fullPath);
FS.lstatAsync(fullPath).then(stat => stat.isDirectory() ? Dir.iterate(fullPath) : resolve(fullPath));
});
} else {
reject(`The path '${path}' is not a directory.`)
}
});
})
}
}
Run Code Online (Sandbox Code Playgroud)
这是我使用/消费它的方式
Dir.iterate(ProjectPaths.client) …Run Code Online (Sandbox Code Playgroud) 关于承诺的另一个问题.我有这种情况:
Service.prototype.parse = function (data) {
var deferred = $.Deferred();
var arr = [];
for (var i = 0; i < data.length; i++) {
var details = new Details();
$.when(details).then(function (data) {
arr.push(data);
deferred.resolve(arr);
});
}
return deferred.promise;
};
Run Code Online (Sandbox Code Playgroud)
代码中的其他地方:
...
$.when(parse()).then(function (resp) {
//...
});
Run Code Online (Sandbox Code Playgroud)
承诺在某些时候得到解决,但最初resp的长度为1.
如何等待parse()解决所有问题并返回数组?
我问了这个问题,并被告知要避免 Promise 构造函数反模式。我通读了链接的文章,但我不确定如何不使用反模式。这是函数:
db.getUserCount = function () {
return new Promise (function (resolve, reject) {
db.users.count().then(function (result) {
resolve (result);
}, function(e) {
reject (e);
});
});
Run Code Online (Sandbox Code Playgroud)
我所有的数据库查询都像上面那样编码。这是我不使用反模式的尝试,但由于我不完全理解它,我认为这种方式也不正确:
db.getUserCount = function () {
return new Promise (function (resolve, reject) {
db.users.count().then(function (result) {
return (result);
}).then(function(result) {
resolve(result);
}).catch(function(err) {
reject(err);
});
});
};
Run Code Online (Sandbox Code Playgroud)
因为我想写出好的代码,如果有人能花一点时间向我展示一个不使用反模式来使用上述函数的例子,那就太好了。
我希望在通过某些条件解决后停止承诺链.下面的代码可能有助于理解我在说什么.
function update(id, data) {
return new Promise((resolve, reject) => {
let conn;
pool.get()
.then((db) => {
conn = db;
if(Object.keys(data).length === 0) {
return resolve({ updated: 0 });
}
else {
return generateHash(data.password);
}
})
.then((hash) => {
conn.query("UPDATE ... ", (err, queryResult) => {
if(err) {
throw err;
}
resolve({ updated: queryResult.affectedRows });
});
})
.catch((err) => { ... })
});
}
Run Code Online (Sandbox Code Playgroud)
请注意,pool.get()是promise包装的API,用于从我创建的MySQL模块获取连接池.
我正在尝试做的是更新用户数据.并且为了节省服务器资源,如果没有要更新的数据,我避免更新(Object.keys(data).length === 0).
当我尝试这个代码时,即使没有数据要更新,第二个(更新数据库)总是会发生!
我读过这篇文章,但没有奏效.当我调用"return resolve();"时为什么没有停止承诺链?我该如何正确地阻止它?我真的很喜欢使用Promises,但有时候,这种事情会让我发疯.非常感谢帮助我解决这个问题.谢谢!
PS无论如何,我正在使用节点v6.2.2.
我知道这不在a的范围内,Array.map但是我想等到上一个项目完成其承诺之后再开始下一个项目.碰巧我需要等待前一个条目保存在数据库中才能向前移动.
const statsPromise = stats.map((item) => {
return playersApi.getOrAddPlayer(item, clubInfo, year); //I need these to wait until previous has finished its promise.
});
Promise.all(statsPromise)
.then((teamData) => {
..//
});
Run Code Online (Sandbox Code Playgroud)
playersApi.getOrAddPlayer 返回一个 new Promise
编辑
阅读更多内容,显示playerApi.getOrAddPlayer似乎很重要
getOrAddPlayer: function (item, clubInfo, year) {
return new Promise((resolve, reject) => {
var playerName = item.name.split(' '),
fname = playerName[0].caps(),
sname = playerName[1].caps();
Players.find({
fname: fname,
sname: sname,
}).exec()
.then(function(playerDetails, err){
if(err) reject(err);
var savePlayer = new Players();
//stuff
savePlayer.save()
.then(function(data, err){
if(err) …Run Code Online (Sandbox Code Playgroud) 我已经看了几个关于promises递归的问题,并对如何正确实现它们感到困惑:
我把一个简单的例子(见下文)放在一起 - 这只是一个例子,所以我可以理解如何使用promises工作进行递归,而不是代表我正在工作的代码.
Net-net,我想要解决的承诺,但根据节点上的输出,它无法解决.有关如何解决问题的任何见解?
var i = 0;
var countToTen = function() {
return new Promise(function(resolve, reject) {
if (i < 10) {
i++;
console.log("i is now: " + i);
return countToTen();
}
else {
resolve(i);
}
});
}
countToTen().then(console.log("i ended up at: " + i));
Run Code Online (Sandbox Code Playgroud)
和控制台上的输出:
> countToTen().then(console.log("i ended up at: " + i));
i is now: 1
i is now: 2
i is now: 3
i is now: 4
i is now: 5 …Run Code Online (Sandbox Code Playgroud) 我的Angular 5项目中有一个服务,其中包含一些配置状态:
@Injectable
export class FooService {
isIncognito: boolean = null;
constructor() {
// I want Angular to wait for this to resolve (i.e. until `isIncognito != null`):
FooService.isIncognitoWindow()
.then( isIncognito => {
this.isIncognito= isIncognito;
} );
}
private static isIncognitoWindow(): Promise<boolean> {
// /sf/ask/203655721/
// https://developer.mozilla.org/en-US/docs/Web/API/LocalFileSystem
return new Promise<boolean>( ( resolve, reject ) => {
let rfs = window['requestFileSystem'] || window['webkitRequestFileSystem'];
if( !rfs ) {
console.warn( "window.RequestFileSystem not found." );
resolve( false );
}
const typeTemporary = 0;
const …Run Code Online (Sandbox Code Playgroud) 我有一个类方法,该方法将类中的其他方法链接在一起,并在类的另一个实例上调用一个方法:
class Thing {
doSomething(nextThing) {
return new Promise((resolve) =>
this.initialize()
.then(() => this.doA())
.then(() => {
nextThing.initialize(); // call initialize() on another instance
return this.doB();
})
.then(() => this.doC())
.then(resolve)
);
}
initialize() {
return new Promise((resolve) => {
// take a long time to do something
// ...
// ...
resolve();
});
}
doA() { return new Promise((resolve) => resolve()); }
doB() { return new Promise((resolve) => resolve()); }
doC() { return new Promise((resolve) => resolve()); }
} …Run Code Online (Sandbox Code Playgroud) 首先,我必须提到我已经在stackoverflow中查看了很多问题,但很多问题都没有回答我的问题.更不用说很多甚至没有答案.
如何实现以下功能,确保完成functionB()后执行functionA()?
注意:我不想将我的异步函数转换为,new Promise(resolve=>{...})
因为我必须转换someServiceThatMakesHTTPCall()调用堆栈中的以及任何其他异步函数,这是一个很大的改变.
function functionThatCannotHaveAsyncKeyword() {
functionA()
.then(async function() {
await functionB();
})
.then(function() {
console.log('last');
});
}
async function functionA() {
console.log('first');
await someServiceThatMakesHTTPCall();
}
async function functionB() {
console.log('second');
await someServiceThatMakesHTTPCall();
}
Run Code Online (Sandbox Code Playgroud) promise ×10
javascript ×7
node.js ×3
asynchronous ×2
recursion ×2
angular ×1
async-await ×1
bluebird ×1
ecmascript-6 ×1
es6-promise ×1
jquery ×1
typescript ×1