为什么Javascript承诺无法解决问题?

时间:2016-10-24 22:00:14

标签: javascript promise

我正在尝试在项目中使用JavaScript承诺,并且事件的顺序是意外的。我已经使用测试承诺将其缩小为一个小型演示。

testPromises = function(promiseNum){
    return new Promise(function(resolve, reject) {
        console.log ('handling promise '+promiseNum);
        setTimeout(function(){
            console.log("resolving testPromises "+promiseNum);
            resolve();
        },2000)
    });
};

然后我这样称呼它:

testPromises(1).then(testPromises(2)).then(testPromises(3))
.then(function(value) {
        console.log('all promises resolved');
}, function(reason) {
        console.log('some promise was rejected');
});

这是控制台输出:

handling promise 1
handling promise 2
handling promise 3
resolving testPromises 1
all promises resolved
resolving testPromises 2
resolving testPromises 3

如何获得输出:

handling promise 1
resolving testPromises 1
handling promise 2
resolving testPromises 2
handling promise 3
resolving testPromises 3
all promises resolved

3 个答案:

答案 0 :(得分:5)

.then()需要一个函数引用。当你做这样的事情时:

.then(testPromises(2))

您正在立即执行函数testPromise()并将返回值传递给.then()。这几乎不是你想要的(除非testPromises()返回另一个函数)。

相反,你想要的是这个:

.then(function() {
    return testPromises(2);
})

或者,您可以使用.bind()

.then(testPromises.bind(null, 2))

所以,你的整个链看起来像这样:

testPromises(1).then(function() {
    return testPromises(2);
}).then(function() {
    return testPromises(3);
}).then(function(value) {
    console.log('all promises resolved');
}, function(reason) {
    console.log('some promise was rejected');
});

或者,使用.bind()

testPromises(1)
  .then(testPromises.bind(null, 2))
  .then(testPromises.bind(null, 3))
  .then(function(value) {
        console.log('all promises resolved');
  }, function(reason) {
        console.log('some promise was rejected');
  });

如果您经常这样做,可以为testPromises()制作一个可以返回另一个函数的咖喱包装器。这基本上就是上面.bind()所做的事情,但是一旦你声明了你的包装函数,语法就会更加漂亮。

function tp(arg) {
    return function() {
        return testPromises(arg);
    }
}

然后,因为该包装器返回另一个函数,所以你可以这样做:

testPromises(1).then(tp(2)).then(tp(3))
.then(function(value) {
    console.log('all promises resolved');
}, function(reason) {
    console.log('some promise was rejected');
});

答案 1 :(得分:2)

这是获取所需输出的代码:

testPromises(1).then(function(){
  return testPromises(2);
}).then(function(){
  return testPromises(3);
}).then(function(value) {
  console.log('all promises resolved');
}, function(reason) {
  console.log('some promise was rejected');
});

Promise 异步解析,但同步创建

testPromises(1).then(testPromises(2)).then(testPromises(3))

或多或少喜欢做

p1 = testPromises(1)
p2 = testPromises(2)
p3 = testPromises(3)

p1.then(p2).then(p3)

由于new Promise是同步的,您将看到的前3行将是

handling promise 1
handling promise 2
handling promise 3

答案 2 :(得分:0)

那么,

handling promise 1
handling promise 2
handling promise 3

首先发生,因为这些调用独立于Promise工作流,它们在您创建每个Promise对象时立即执行,因为这样做可以显式执行每个函数,如testPromises(1)等等。 / p>

但问题是,您对console.log('all promises resolved');的调用仅取决于testPromises(1)正在解决,所有其他承诺都已分离。

为了同步它们,每个.then调用必须返回一个Promise,你可以使用function并返回Promises testPromises函数已经返回。



testPromises = function(promiseNum){
    return new Promise(function(resolve, reject) {
        console.log ('handling promise '+promiseNum);
        setTimeout(function(){
            console.log("resolving testPromises "+promiseNum);
            resolve();
        },0)
    });
};

testPromises(1).then(function() {
  return testPromises(2);
}).then(function() {
  return testPromises(3);
}).then(function(value) {
        console.log('all promises resolved');
}, function(reason) {
        console.log('some promise was rejected');
});