Javascript 如何同步解决es6承诺链?
我有一个来自库的函数,它返回一个承诺。我需要多次运行这个函数,但每次迭代都必须等到上一个任务完成 我的假设是我可以做到这一点:Javascript 如何同步解决es6承诺链?,javascript,promise,Javascript,Promise,我有一个来自库的函数,它返回一个承诺。我需要多次运行这个函数,但每次迭代都必须等到上一个任务完成 我的假设是我可以做到这一点: promiseReturner(1) .then(promiseReturner(2) .then(promiseReturner(3) .then(...) 可以使用循环来简化: var p = Promise.resolve(); for (var i=1; i<=10; i++) { p = p.then(promiseReturner(i
promiseReturner(1)
.then(promiseReturner(2)
.then(promiseReturner(3)
.then(...)
可以使用循环来简化:
var p = Promise.resolve();
for (var i=1; i<=10; i++) {
p = p.then(promiseReturner(i));
}
var p=Promise.resolve();
对于(var i=1;i,您的“非循环”解决方案也不应该起作用。您必须将函数传递给。然后
,而不是承诺:
var p = Promise.resolve();
for (var i=1; i<=10; i++) {
(function(i) {
p = p.then(function() {
return promiseReturner(i);
});
}(i));
}
或(即ES5):
var p=Promise.resolve();
对于(var i=1;i您可以使用es6生成器和类似的库来使用async/await
co(函数*(){
而(小于等于10){
var结果=收益承诺。解决(真);
}
返回结果;
}).然后(函数(值){
console.log(值);
},函数(err){
控制台错误(错误堆栈);
});
这里有一些详细的工作原理:这里有一个我用来解决相同问题的解决方案:
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');
})
var recursiveFunction=函数(值){
返回新承诺(功能(解决、拒绝){
if(values.length如果您使用的是es6,那么您可以使用array.reduce
来实现这一点。我认为这相当巧妙
const functions=[/*返回promises*/]的函数数组;
const finalPromise=functions.reduce(异步(承诺,异步)=>{
等待承诺;
返回asyncFn();
},Promise.resolve());
您可以通过运行代码,它将暂停对每个返回promise的函数的执行,并等待promise得到解决:
var promiseReturner=函数(i){
返回新承诺(功能(解决、拒绝){
setTimeout(函数(){
解决(“结果为”+i)
}, 1000);
});
};
函数synchronousCode(){
对于(var i=1;i而言,同步执行彼此之间的承诺可能很棘手。下面我举了一个使用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);
});
也许更清楚:“你必须传递一个函数,返回一个承诺”?我之前曾尝试将其包装到函数中,但它似乎只运行最后一个承诺。为什么将其包装到自调用函数中似乎可以修复它?@BenDavis:.tl;dr:JavaScript只有函数作用域,而不是块作用域,因此每个函数都引用相同的I
。这是通过let
btw修复的。啊,谢谢!我我想我也把自己弄糊涂了,因为我认为我的promiseReturner函数本身就是一个函数,但没有意识到我正在传递该函数的结果(而不是函数本身)。你会认为已经编写了15年的人会明白这一点。想想看。@BenDavis::)如果promiseReturner
不需要参数,您可以执行p=p.then(promiseReturner);
(注意,我没有调用函数)。但实际上,iLife(立即调用的函数表达式)有一个替代方法,.bind
:p=p.then(promiseReturner.bind(null,I))
。promiseReturner(n)
是返回承诺还是作出承诺返回函数?阅读npm自述页面后,听起来这个库本质上是es6“wait”的一个过于复杂的自定义实现如果我错了,请纠正我,但我真的不相信用javascript为javascript编写自定义评估引擎是个好主意。
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);
});
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');
})
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);
});