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);
  });