【问题标题】:Promise chain with setTimeout带有 setTimeout 的承诺链
【发布时间】:2020-07-20 23:06:48
【问题描述】:

我是 javascript 的大一新生,现在正在学习 Promise 部分。

下面我一直在尝试使用 setTimeout 编写一个承诺链,并期望它在 2 秒后打印“第一个结果”,并在另外 2 秒后打印“第二个结果”。但是,它会同时打印“第一个结果”和“第二个结果”。

谁能告诉我哪里出错了?

var doSomething = new Promise(function(resolve,reject){ 
    setTimeout(function(){ 
        resolve('first result');  
    },2000); 
});

var doSomethingElse = new Promise(function(resolve,reject){ 
    setTimeout(function(){
        resolve('second result');  
    },2000); 
});

doSomething
    .then(function(result){
    console.log("This is the "+result); 
    return doSomethingElse;
    })
    .then(function(result){
        console.log("This is the "+result);
});

=============================

编辑: 所以当我如下写promise时,executor函数(setTimeout)立即开始计数,并在2秒后解决。

var doSomething = new Promise(function(resolve,reject){   // starts counting here
    setTimeout(function(){ 
        resolve('first result');  
    },2000); 
});

但是,如果我将 promise 包装在如下函数中,则执行器函数 (setTimeout) 仅在 我调用该函数后开始计数。这是正确的吗?

function doSomething(){
    return new Promise(function(resolve,reject){
        setTimeout(function(){
            resolve('first result');
        },2000);
    })
}
doSomething(); // starts counting here

【问题讨论】:

  • 你同时开始了两个承诺。您只是将它们链接起来,以便以定义的顺序打印它们的响应。如果你想在第一个 resolve 后开始第二个 promise,你需要把 new Promise 放到第一个的 .then() 中。
  • 编辑中的问题:是的,是的。

标签: javascript promise settimeout


【解决方案1】:

正如所写,doSomething 承诺和doSomethingElse 承诺是在非常快速的连续创建的,并且将在大约 2 秒后快速连续解决。

代码中没有任何内容导致这两个进程是连续的。为此,您需要确保 doSomethingElsedoSomething 完成后 2 秒开始。

您可以通过多种方式组织代码来实现这一点。

例如,您可以将 new Promise(...) 表达式直接写入您的 Promise 链而不进行任何分配:

new Promise(function(resolve, reject) {
    setTimeout(function() {
        resolve('first result');
    }, 2000);
})
.then(function(result) {
    console.log("This is the " + result);
    return new Promise(function(resolve, reject) {
        setTimeout(function() {
            resolve('second result');
        }, 2000);
    });
})
.then(function(result) {
    console.log("This is the " + result);
});

或者,您可以将doSomethingdoSomethingElse 编写为函数:

function doSomething() {
    return new Promise(function(resolve, reject) {
        setTimeout(function() {
            resolve('first result');
        }, 2000);
    });
}
function doSomethingElse() {
    return new Promise(function(resolve, reject) {
        setTimeout(function() {
            resolve('second result');
        }, 2000);
    });
}

doSomething()
.then(function(result) {
    console.log("This is the " + result); 
    return doSomethingElse();
})
.then(function(result) {
    console.log("This is the " + result);
});

或者,您可以编写一个 doSomething() 函数并调用它两次:

function doSomething(value) {
    return new Promise(function(resolve,reject) {
        setTimeout(function() {
            resolve(value);
        },2000);
    });
}

doSomething('first result')
.then(function(result) {
    console.log("This is the " + result); 
    return doSomething('second result');
})
.then(function(result) {
    console.log("This is the " + result);
});

或者,回到 doSomething()doSomethingElse() 作为单独的函数,您可以添加第三个 logResult() 函数来进行日志记录:

function doSomething() {
    return new Promise(function(resolve, reject) {
        setTimeout(function() {
            resolve('first result');
        }, 2000);
    });
}
function doSomethingElse() {
    return new Promise(function(resolve, reject) {
        setTimeout(function() {
            resolve('second result');
        }, 2000);
    });
}
function logResult(result) {
    console.log("This is the " + result); 
}

doSomething()
.then(function(result) {
    logResult(result);
    return doSomethingElse();
})
.then(function(result) {
    logResult(result);
});

上一个例子的一个很好的特点是 Promise 链将简化如下:

function doSomething() {
    return new Promise(function(resolve, reject) {
        setTimeout(function() {
            resolve('first result');
        }, 2000);
    });
}
function doSomethingElse() {
    return new Promise(function(resolve, reject) {
        setTimeout(function() {
            resolve('second result');
        }, 2000);
    });
}
function logResult(result) {
    console.log("This is the " + result); 
}

doSomething()
.then(logResult)
.then(doSomethingElse)
.then(logResult);

如您所见,没有唯一的解决方案。

【讨论】:

    【解决方案2】:

    您正在创建一个承诺并将其分配给doSomething。第一个计时器开始倒计时。

    然后您立即创建另一个承诺并将其分配给doSomethingElse。第二个计时器开始倒计时。


    在第一个promise解决之后创建第二个promise。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-10-04
      • 2017-01-25
      • 1970-01-01
      • 2020-02-07
      • 2016-12-09
      相关资源
      最近更新 更多