如何检查异步函数何时通过Promise完成了执行?

时间:2018-07-13 06:05:39

标签: javascript promise es6-promise

我有一个异步函数,正在被另一个函数调用。我想在异步功能完成执行后执行一些操作。我正在尝试使用诺言来做到这一点。我认为我在使用诺言方面出了错。这是我的代码:

function foo(){
setTimeout(()=>console.log("hello world"),1000)
}

function bar(){
  return new Promise(function(resolve){
  resolve(foo())
  })
}

bar().then(()=>console.log("foo has completed"))

即使在异步执行完成之前,控制台也会打印“ foo已经完成”。

4 个答案:

答案 0 :(得分:2)

呼叫解决是您应该自己做的事情。由于foo立即返回,因此您的诺言也将立即得到解决。但是,如果满足您的要求,则可以执行以下类似操作。

    public function users()
    {
      return $this->hasMany(User::class, 'id');
    }

    public function commenteduser()
    {
      return $this->users()->join('postcomments', function($join){
      $join->on('users.id', '=', 'postcomments.user_id')
      ->where('postcomments.user_id' ,'=', 'user_id');
    })->select('name');
    }

答案 1 :(得分:1)

如果您花一些时间查看javascript,您会注意到所有异步函数都有某种机制让您知道何时完成。通常是回调或Promise,但有时还包括事件。

您的函数foo()执行异步操作,但是在完成时无法提供任何方法来提醒调用者或其他任何人。这就是导致您遇到问题的原因,并且没有更改foo()的好方法。您可以执行以下操作。

让foo调用回调

您可以更改foo()以在完成后调用回调。然后可能看起来像这样:

 function foo(cb){
    setTimeout(()=>{
        console.log("hello world")
        cb(null, true) // callbacks offen pass an error as their first arg or null if there's no error

    },1000)
}

这样,bar()可以通过回调调用它,然后触发回调或返回promise。在这里,我们将返回一个承诺并将其连接在一起:

function foo(cb){
    console.log("foo called")
    setTimeout(()=>{
        console.log("foo's timeout finished")
        cb(null, true)

    },1000)
}
    
function bar(){
    console.log("car called")
    return new Promise((resolve, reject) =>{
        foo((err, res) => {
            if (err) return reject(err)
            resolve( "foo finished with " + res)
        })
    })
}

bar().then((result)=>console.log("bar has finish and returned: ", result))

或者让Foo兑现承诺

如果foo()仅返回了在完成时已解决的诺言,那么一切都会变得更加容易,因为然后bar()可以先返回诺言,然后调用.then()并在需要时返回处理结果:

function foo(cb) {
  return new Promise(resolve => setTimeout(() => {
    console.log("hello world")
    resolve(true)
  }, 1000))
}

function bar() {
  return foo().then(res => "foo finished with: " + res)
}

bar().then((result) => console.log("bar has finish and returned: ", result))

答案 2 :(得分:0)

我认为您的代码应该是这样的

function foo() {
  return new Promise(function(resolve) {
    setTimeout(() => {
      console.log("hello world");
      resolve();
    }, 1000);
  });
}

function bar() {
  return new Promise(function(resolve) {
    resolve(foo());
  });
}

bar().then(() => console.log("foo has completed"));

答案 3 :(得分:-1)

您将在setTimeout()呼叫中返回一个resolve呼叫。这应该解决它:

function foo(resolve){
setTimeout(()=> { 
  console.log("hello world");
  resolve()
 },1000)
}

function bar(){
  return new Promise(function(resolve){
    return foo(resolve)
  })
}

bar().then(()=>console.log("foo has completed"))