Javascript 同步执行保存在变量中的承诺

Javascript 同步执行保存在变量中的承诺,javascript,promise,es6-promise,Javascript,Promise,Es6 Promise,为了更好地理解承诺链,我起草了一个代码示例,发现自己对这里发生的事情感到非常困惑 假设我们有两个变量存储承诺: const promise1 = new Promise((resolve, reject) => { setTimeout(() => { resolve('promise 1'); }, 1000); }); const promise2 = new Promise((resolve, reject) => { setTimeout(

为了更好地理解承诺链,我起草了一个代码示例,发现自己对这里发生的事情感到非常困惑

假设我们有两个变量存储承诺:

const promise1 = new Promise((resolve, reject) => {
    setTimeout(() => {
    resolve('promise 1');
  }, 1000);
});

const promise2 = new Promise((resolve, reject) => {
    setTimeout(() => {
    resolve('promise 2');
  }, 1000);
});
然后我们就这样把它们链起来:

promise1
  .then(data => {
      console.log(data);
      return promise2;
  })
  .then(data => {
      console.log(data);
  });
这两个console.log似乎同时到达,尽管我预计它们之间会有1秒的停顿。如果我创建返回承诺的函数并将其链接,则行为是相同的:

function firePromise1() {
    return promise1;
} 

function firePromise2() {
    return promise2;
} 

firePromise1()
    .then(data => {
        console.log(data);
        return firePromise2();
    })
   .then(data => {
        console.log(data);
   });
仅当我在promise chain中调用的函数内部或在then block自身中创建一个promise时,我才能看到promise以1秒的间隔一个接一个地解决:

promise1
    .then(data => {
    console.log(data);
    return new Promise((resolve, reject) => {
          setTimeout(() => {
            resolve('promise 2');
          }, 1000);
        });
    })
    .then(data => {
      console.log(data); 
    });
有人能解释一下为什么会这样吗?它是关于JS如何初始化变量并以某种方式连接到Promise立即执行这一事实的吗?我深入研究了不同的资源和文档,但似乎仍然遗漏了一些重要甚至明显的东西。。。谢谢

有人能解释一下为什么会这样吗?是关于如何 初始化变量,并以某种方式连接到 立即执行

是的,正是因为这个。承诺一经宣布即生效。在您的情况下,当您宣布承诺时,它会自动等待1秒,并承诺相同。如果要在第一个操作完成后等待一秒钟,则必须在then块中声明承诺,就像在上一个示例中所做的那样。通常的做法是使用返回承诺的函数:

const getSecondPromise = () => new Promise((resolve, reject) => setTimeout(() => resolve('promise 2' ));

然后,您可以在第一个承诺的then中调用函数,并立即执行第二个承诺。

对于前两个承诺链,包括promise1和promise2作为变量的声明,即:

const promise1 = new Promise((resolve, reject) => {
    setTimeout(() => {
    resolve('promise 1');
  }, 1000);
});

const promise2 = new Promise((resolve, reject) => {
    setTimeout(() => {
    resolve('promise 2');
  }, 1000);
});
声明和分配变量时,赋值运算符的右侧会立即求值,即两个setTimeout函数都会立即启动。这与“正在执行”的承诺无关。你可以通过一个控制台来测试这一点。logPrint me!在两个setTimeout函数中

如果您在以下函数中声明了承诺,然后创建了一个then链,那么您将看到promise1和promise2的日志记录之间有一秒的延迟

function prom1(){
    return new Promise((resolve, reject) => {
        setTimeout(() => {
        resolve('promise 1');
      }, 1000);
    });
}
function prom2(){ 
    return new Promise((resolve, reject) => {
        setTimeout(() => {
        resolve('promise 2');
      }, 1000);
    });
}

Promise是同步获取异步任务的未来值结果的占位符的抽象。当您调用一个函数并返回一个承诺时,您就启动了相关的异步任务,而不是在您将a.链接到承诺的时候。因此,在定义承诺的那一刻,您已经几乎同时启动了异步任务。最好不要存储承诺,而是在需要时调用承诺返回函数

下面是一个承诺返回函数,它使用普通错误优先回调类型异步函数返回承诺

function asyncTask(data){
  return new Promise((v,x) => doAsyncThings(data, (e,r) => e ? x(e) : v(r)));
}
下面是一个使用递归承诺序列器对承诺进行排序的示例

var sequenceAsync=[d,…ds]=>d!==void 0&&asyncTaskd.thenv=>sequenceAsyncds, asyncTask=n=>newpromisev=>setTimeoutn=>console.logn,v,1000,n, 数据=[1,2,3,4,5];
序列数据;一个人不能履行诺言。承诺是价值的结果。创建承诺时,任务已启动。将对setTimeout的调用及其周围的承诺放在firePromise函数中。@Bergi,执行它们可能意味着executer函数,该函数负责承诺解析/拒绝后将表示的值。是的,在调用的函数中调用setTimeout后,它将按预期工作。谢谢!我可能被以下事实分散了注意力:模式让promise=newpromise/*…*/在这之后,promise.then经常用于文档和示例中。然而,似乎没有人像那样把它们拴起来,现在我明白了为什么。还有控制台的把戏。把我打印出来!“内部暂停确实澄清了问题。”娜塔莉亚伊万诺娃很乐意帮忙!: