我有一个异步函数,正在被另一个函数调用。我想在异步功能完成执行后执行一些操作。我正在尝试使用诺言来做到这一点。我认为我在使用诺言方面出了错。这是我的代码:
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已经完成”。
答案 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()
以在完成后调用回调。然后可能看起来像这样:
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()
仅返回了在完成时已解决的诺言,那么一切都会变得更加容易,因为然后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"))