javascript 你如何同步解决一系列 es6 承诺?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/28683071/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do you synchronously resolve a chain of es6 promises?
提问by Ben Davis
I have a function from a library that returns a promise. I need to run this function multiple times, but each iteration must wait until the previous task is done.
我有一个库中的函数,它返回一个承诺。我需要多次运行这个函数,但每次迭代都必须等到上一个任务完成。
My assumption was that I could do this:
我的假设是我可以这样做:
promiseReturner(1)
.then(promiseReturner(2)
.then(promiseReturner(3)
.then(...)
Which could be simplified using a loop:
可以使用循环简化:
var p = Promise.resolve();
for (var i=1; i<=10; i++) {
p = p.then(promiseReturner(i));
}
However, when I do this each promise in the chain is executed at the same time, instead of one after the other as .then()
seems to imply. Clearly I'm missing something fundamental about promises -- but after reading several tutorials and blog posts I'm still lost.
但是,当我这样做时,链中的每个承诺都会同时执行,而不是像.then()
暗示的那样一个接一个地执行。显然,我遗漏了一些关于 Promise 的基本知识——但在阅读了几篇教程和博客文章后,我仍然迷失了方向。
回答by Felix Kling
Your "non-loop" solution shouldn't work either. You have to pass a functionto .then
, not a promise:
您的“非循环”解决方案也不应该起作用。您必须将函数传递给.then
,而不是承诺:
var p = Promise.resolve();
for (var i=1; i<=10; i++) {
(function(i) {
p = p.then(function() {
return promiseReturner(i);
});
}(i));
}
If that function returns a promise, then you get that chaining effect.
如果该函数返回一个promise,那么你就会得到那个连锁效应。
More info about promises on MDN.
有关MDN承诺的更多信息。
Can be simplified with let
(and arrow functions):
可以用let
(和箭头函数)简化:
var p = Promise.resolve();
for (let i=1; i<=10; i++) {
p = p.then(() => promiseReturner(i));
}
Or .bind
(which is ES5):
或者.bind
(这是 ES5):
var p = Promise.resolve();
for (var i=1; i<=10; i++) {
p = p.then(promiseReturner.bind(null, i));
}
回答by Alastair Brayne
If you are using es6, you can achieve this using array.reduce
. I think quite neatly.
如果您使用的是 es6,则可以使用array.reduce
. 我觉得很巧妙。
const functions = [/* array of functions which return promises */];
const finalPromise = functions.reduce(async (promise, asyncFn) => {
await promise;
return asyncFn();
}, Promise.resolve());
回答by eguneys
You can use async/await
using es6 generators and a library like co.
您可以使用async/await
es6 生成器和像co这样的库。
co(function* () {
while(upto < 10) {
var result = yield Promise.resolve(true);
}
return result;
}).then(function (value) {
console.log(value);
}, function (err) {
console.error(err.stack);
});
Here's some detail how this works: http://davidwalsh.name/async-generators
以下是其工作原理的一些详细信息:http: //davidwalsh.name/async-generators
回答by Bilal Soomro
Here's a solution which I used to solve the same problem:
这是我用来解决相同问题的解决方案:
var recursiveFunction = function(values) {
return new Promise(function(resolve, reject) {
if (values.length <= 0) {
return resolve();
} else {
return promiseReturner(values[0]).then(function() {
values.shift();
return recursiveFunction(values).then(function() {
resolve();
});
});
}
});
}
recursiveFunction([1,2]).then(function(r) {
console.warn('Finished solving promises sequentially');
})
回答by Quantyle
Executing promises synchronously with respect to each other can be tricky. I've included an example below that uses Axios promises, but you can replace them with your own. Good luck!
相对于彼此同步执行承诺可能会很棘手。我在下面包含了一个使用 Axios 承诺的示例,但您可以将它们替换为您自己的。祝你好运!
const get = (endpoint = '/', params = {}) => {
// return axios promise
return axios({
method: 'get',
url: apiHost + endpoint,
headers: { 'Authorization': 'Token ' + this.state.token },
params: params,
});
};
get('/api/some-endpoint/')
.then((response) => {
console.log(response);
//return next promise
return get('/api/another-endpoint/');
}).then((response) => {
console.log(response);
// return next promise
return get('/api/yet-endpoint');
}).then((response) => {
console.log(response);
// return next promise
return get('/api/last-endpoint/');
}).then((response) => {
console.log(response);
// finished, no more promises left in the chain
})
.catch(function (error) {
console.log('Error getting data', error);
});
回答by amaksr
You can run your code via nsynjs, it will pause execution on each function that returns promise, and will wait until promise is resolved:
你可以通过nsynjs运行你的代码,它会暂停每个返回 promise 的函数的执行,并等待 promise 被解决:
var promiseReturner = function(i) {
return new Promise(function(resolve, reject) {
setTimeout(function(){
resolve("result is "+i)
}, 1000);
});
};
function synchronousCode() {
for (var i=1; i<=10; i++) {
var p=promiseReturner(i); // nsynjs will pause here until promise is resolved
console.log(p.data); // `data` will contain result of the promise
}
};
nsynjs.run(synchronousCode, null, function(){
console.log("finish");
});
<script src="https://rawgit.com/amaksr/nsynjs/master/nsynjs.js"></script>