我曾经知道这意味着什么,但我现在正在努力...
这基本上是说document.onload吗?
(function () {
})();
Run Code Online (Sandbox Code Playgroud) 我编写的代码看起来像:
function getStuffDone(param) { | function getStuffDone(param) {
var d = Q.defer(); /* or $q.defer */ | return new Promise(function(resolve, reject) {
// or = new $.Deferred() etc. | // using a promise constructor
myPromiseFn(param+1) | myPromiseFn(param+1)
.then(function(val) { /* or .done */ | .then(function(val) {
d.resolve(val); | resolve(val);
}).catch(function(err) { /* .fail */ | }).catch(function(err) {
d.reject(err); | reject(err);
}); | });
return d.promise; /* or promise() */ | });
} | }
Run Code Online (Sandbox Code Playgroud)
有人告诉我这个被称为" 延迟反模式 "或" Promise构造函数反模式 ",这个代码有什么不好,为什么这被称为 …
请考虑以下以串行/顺序方式读取文件数组的代码.readFiles返回一个promise,只有在按顺序读取所有文件后才会解析.
var readFile = function(file) {
... // Returns a promise.
};
var readFiles = function(files) {
return new Promise((resolve, reject) =>
var readSequential = function(index) {
if (index >= files.length) {
resolve();
} else {
readFile(files[index]).then(function() {
readSequential(index + 1);
}).catch(reject);
}
};
readSequential(0); // Start!
});
};
Run Code Online (Sandbox Code Playgroud)
上面的代码可以工作,但我不喜欢按顺序进行递归递归.是否有一种更简单的方法可以重写此代码,以便我不必使用我的奇怪readSequential功能?
最初我试图使用Promise.all,但这导致所有readFile调用同时发生,这不是我想要的:
var readFiles = function(files) {
return Promise.all(files.map(function(file) {
return readFile(file);
}));
};
Run Code Online (Sandbox Code Playgroud) 使用ES6承诺,如何在不定义解析逻辑的情况下创建承诺?这是一个基本的例子(一些TypeScript):
var promises = {};
function waitFor(key: string): Promise<any> {
if (key in promises) {
return promises[key];
}
var promise = new Promise(resolve => {
// But I don't want to try resolving anything here :(
});
promises[key] = promise;
return promise;
}
function resolveWith(key: string, value: any): void {
promises[key].resolve(value); // Not valid :(
}
Run Code Online (Sandbox Code Playgroud)
使用其他promise库可以轻松完成.以JQuery为例:
var deferreds = {};
function waitFor(key: string): Promise<any> {
if (key in promises) {
return deferreds[key].promise();
}
var def = $.Deferred();
deferreds[key] = …Run Code Online (Sandbox Code Playgroud) 编辑
代码为#1.继续重试,直到诺言解决(语言的任何改进社区等?)
Promise.retry = function(fn, times, delay) {
return new Promise(function(resolve, reject){
var error;
var attempt = function() {
if (times == 0) {
reject(error);
} else {
fn().then(resolve)
.catch(function(e){
times--;
error = e;
setTimeout(function(){attempt()}, delay);
});
}
};
attempt();
});
};
Run Code Online (Sandbox Code Playgroud)
使用
work.getStatus()
.then(function(result){ //retry, some glitch in the system
return Promise.retry(work.unpublish.bind(work, result), 10, 2000);
})
.then(function(){console.log('done')})
.catch(console.error);
Run Code Online (Sandbox Code Playgroud)
#2的代码继续重试,直到条件then以可重用的方式满足结果(条件是变化的).
work.publish()
.then(function(result){
return new Promise(function(resolve, reject){
var intervalId = setInterval(function(){
work.requestStatus(result).then(function(result2){
switch(result2.status) { …Run Code Online (Sandbox Code Playgroud) 我需要Promise.each在蓝鸟上使用.但是当我看到捆绑文件时,我实际上是在考虑使用蓝鸟.
任何人都可以使用像bluebird这样 Promise.each没有依赖关系的函数给我一个例子.
所以我有一个承诺,从服务器收集数据,但一次只收集50个响应.我收集了250份回复.
我可以像下面一样汇总承诺
new Promise((resolve, reject) => {
resolve(getResults.get())
})
.then((results) => {
totalResults.concat(results)
return getResults.get()
})
.then((results) => {
totalResults.concat(results)
return getResults.get()
}).then((results) => {
totalResults.concat(results)
return getResults.get()
})
Run Code Online (Sandbox Code Playgroud)
在这种情况下,我只需要250个结果,所以这似乎是一个可管理的解决方案,但是有一种方法可以在一个循环中汇总promise.所以我运行一个循环5次,每次运行下一个承诺.
对不起,我是承诺的新手,如果这是回调,这就是我要做的.
编辑:为什么这不是重复的:因为Cypress,只是读取而不是将所有内容标记为重复。
编辑 2:另外,请参阅答案以更好地理解通常的异步for循环问题与此问题之间的差异。
我正在编写 cypress 测试,我想创建一个 cypress 命令,用用户列表填充我的数据库。我希望创建循环在移动到下一个用户之前等待每个用户被创建(因为我希望以特定顺序完成)。
现在,我的循环如下所示:
Cypress.Commands.add("populateDb", (users) => {
var createdItems = []
for (const user of users) {
cy.createUser(user, 'passe').then(response => {
createdUsers.unshift(response.body.user)
})
}
return createdItems
})
Run Code Online (Sandbox Code Playgroud)
当然,这个循环在移动到下一个用户之前不会等待每个用户被创建(我想要“顺序处理”,而不是“并行然后等待所有承诺解决”)
我在这里阅读了有关异步 for 循环的答案:
但我似乎找不到我想要的东西,主要是因为 cypress 不允许我将我的函数声明为异步,如下所示:
Cypress.Commands.add("populateDb", async (users) => {
//Some code
})
Run Code Online (Sandbox Code Playgroud)
如果我不声明它,async我将无法使用await.
是不是有一些get()方法之王只是同步等待 Promise 解决?
我想在我的代码的一部分中进行同步循环.saveInDatabase函数检查数据库中是否已存在项标题(字符串).这就是为什么它不能并行解决,否则条件永远不会适用(并会产生重复).
Promise.all(arr.map(item => {
saveInDatabase(item).then((myResult) => ... );
}));
Run Code Online (Sandbox Code Playgroud)
我试图将此函数封装到单独的promises中,也尝试使用npm包(synchronous.js,sync),但似乎它不适合我的代码.
也许这个解决方案完全愚蠢.您是否认为通过同步循环(例如foreach)替换promise.all更好?问题是我需要每次迭代的结果......
我正在使用Node 6.11.2.你能给我一些处理它的提示吗?先感谢您.
如果是使用 Node.js 编写的 JavaScript 程序,它将查看所有员工,获取一些数据,进行一些计算,然后将其发送回另一台服务器:
// without error handling to keep it simple for now
for (let employee of employees) {
new Promise(function(resolve) {
fetch(someUrlToServerA + employee.id).then(resolve);
}.then((data) => {
let result = doCalculations(data);
return postData(someUrlToServerB + employee.id, result).then(resolve);
}.then(() => console.log("Finished for", employee.id));
}
console.log("All done.");
Run Code Online (Sandbox Code Playgroud)
如果使用 async/await 编写,它可能大致相当于:
(async function(){
for (let employee of employees) {
data = await fetch(someUrlToServerA + employee.id);
let result = doCalculations(data);
await postData(someUrlToServerB + employee.id, result);
console.log("Finished for", employee.id);
}
console.log("All done.");
})(); …Run Code Online (Sandbox Code Playgroud) javascript ×9
promise ×8
bluebird ×3
es6-promise ×3
asynchronous ×2
node.js ×2
q ×2
async-await ×1
cypress ×1
iife ×1
mongoose ×1
sequential ×1